use Benchmark qw(cmpthese);
sub rbyte { int rand 256 }
my @unsorted;
for (1..10000) { push @unsorted, join '.', rbyte, rbyte, rbyte, rbyte }
sub sort_by_ip_address
{
return sort { pack("C4",split(/\./,$a)) cmp pack("C4",split(/\./,$b)) } @_
}
sub sort_faster
{
return map {$_->[1]} sort {$a->[0] cmp $b->[0]} map {[(pack('C4',split(/\./,$_))), $_]} @_
}
sub sort_fastest
{
return
map { join ".", unpack "C*", $_ }
sort
map { pack "C*", split /\./, $_ }
@_;
}
{
my $slow= join " ", sort_by_ip_address(@unsorted);
my $fast= join " ", sort_faster(@unsorted);
my $tye= join " ", sort_fastest(@unsorted);
warn "slow/fast disagree\n" if $slow ne $fast;
warn "slow/tye disagree\n" if $slow ne $tye;
}
my @sorted;
cmpthese( 10, {
' slow' => sub { @sorted = sort_by_ip_address(@unsorted) },
'faster' => sub { @sorted = sort_faster(@unsorted) },
' tye' => sub { @sorted = sort_fastest(@unsorted) },
});
__END__
####
map { join ".", unpack "C*", $_ }
sort
map { pack "C*", split /\./, $_ }
@ips;
####
Rate slow faster tye
slow 0.575/s -- -75% -83%
faster 2.34/s 307% -- -32%
tye 3.45/s 501% 48% --