This is one that can easily be done the wrong way, and seems to be done wrong as often as it is done right. I took it upon myself to compile several different ways of sorting IPv4 addresses, and benchmarked them for your benefit:
#!/usr/bin/perl use strict; use warnings; use Benchmark qw(cmpthese); use Socket qw(inet_aton inet_ntoa); chomp( my @ips=(<>) ); cmpthese(-10, { inet_grt => sub { my @sorted = map { inet_ntoa $_ } sort { $a cmp $b } map { inet_aton $_ } @ips; }, inet_grt2 => sub { my @sorted = map { unpack 'x4A*' } sort { $a cmp $b } map { pack('A4A*', inet_aton($_), $_) } @ips; }, inet_orc => sub { my @sorted = sort by_ip @ips; }, splitwise => sub { my @sorted = map $_->[0], sort { $a->[1] <=> $b->[1] or $a->[2] <=> $b->[2] or $a->[3] <=> $b->[3] or $a->[4] <=> $b->[4] } map [$_, split /\./], @ips; }, split_int => sub { my @sorted = map { join '.', unpack("CCCC", pack("N",$_)) +} sort { $a <=> $b } map { unpack("N",pack("CCCC",split /\./)) } @ips; }, naive => sub { my @sorted = sort { my @a = split /\./, $a; my @b = split /\./, $b; $a[0] <=> $b[0] or $a[1] <=> $b[1] or $a[2] <=> $b[2] or $a[3] <=> $b[3] } @ips; }, }); { my %cache; sub by_ip { my $orc_a = ($cache{$a} ||= inet_aton($a)); my $orc_b = ($cache{$b} ||= inet_aton($b)); $orc_a cmp $orc_b; } } __END__ Rate naive split_int splitwise inet_orc inet_grt2 in +et_grt naive 8.65/s -- -86% -88% -89% -93% + -96% split_int 62.5/s 622% -- -12% -17% -52% + -69% splitwise 71.1/s 722% 14% -- -6% -45% + -65% inet_orc 75.4/s 772% 21% 6% -- -42% + -63% inet_grt2 129/s 1393% 107% 82% 71% -- + -36% inet_grt 201/s 2229% 222% 183% 167% 56% + --
My input was a list of 1000 random IP addresses generated by nmap, listed in the HTML comments for this node
UPDATE: Thanks to ELISHEVA for catching a bug in naive that made it think the input was sorted. Updated benchmarks show it is 86% slower than the nearest competition
| print pack("A25",pack("V*",map{1919242272+$_}(34481450,-49737472,6228,0,-285028276,6979,-1380265972))) |
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: RFC: Sorting IPv4 addresses
by salva (Canon) on Oct 06, 2009 at 23:26 UTC | |
by bv (Friar) on Oct 07, 2009 at 01:44 UTC | |
|
Re: RFC: Sorting IPv4 addresses
by ikegami (Patriarch) on Oct 06, 2009 at 22:42 UTC | |
by bv (Friar) on Oct 07, 2009 at 01:33 UTC | |
by ikegami (Patriarch) on Oct 07, 2009 at 01:57 UTC | |
by bv (Friar) on Oct 07, 2009 at 14:10 UTC | |
|
Re: RFC: Sorting IPv4 addresses
by ELISHEVA (Prior) on Oct 07, 2009 at 18:54 UTC | |
by ikegami (Patriarch) on Oct 07, 2009 at 19:09 UTC | |
by bv (Friar) on Oct 07, 2009 at 19:05 UTC |