Update: Regarding performance, stringification "@$p" reaches join(':',@$p) in Perl 5.22 and onwards. See this post.
Hi LanX,
Added lan_hash and lan_look, based on str_hash and str_look respectively. The stringification is a nice catch. Surprisingly, I didn't expect for it to run slower compared to join(':', @$p) and thought as fast or faster.
sub lan_hash {
# print "LanX_hash---------------\n";
my %cells;
# insert the points into the hash
for my $p (@points) {
my $h = $p->[0] . ' ' . $p->[1];
my ( $x, $y ) = split ' ', $h;
# print "x='$p->[0]' y='$p->[1]' h='$h' (x='$x' y='$y')\n";
if ($x != $p->[0]) { die; }
if ($y != $p->[1]) { die; }
$cells{$h} = undef;
# ++$cells{$h};
}
scalar(keys %cells) == $npoints or die;
# lookup each points in the hash
for my $p (@points) {
my $h = $p->[0] . ' ' . $p->[1];
exists $cells{$h} or die;
}
exists $cells{'notfound'} and die;
exists $cells{'notfound2'} and die;
exists $cells{'notfound3'} and die;
return \%cells;
}
sub lan_look {
my $cells = shift;
for my $p (@points) {
exists $cells->{ "@$p" } or die;
}
exists $cells->{'notfound'} and die;
exists $cells->{'notfound2'} and die;
exists $cells->{'notfound3'} and die;
}
my $big_ref = big_hash();
my $lan_ref = lan_hash();
my $mat_ref = mat_hash();
my $pak_ref = pak_hash();
my $st2_ref = str_hash();
my $st3_ref = str_hash();
my $str_ref = str_hash();
timethese 200000, {
Big => sub { big_look($big_ref) }, # $cells->{ ($p->[1] << 32) | ($
+p->[0] & 0xFFFFFFFF) }
Lan => sub { lan_look($lan_ref) }, # $cells->{ "@$p" }
Mat => sub { mat_look($mat_ref) }, # $cells->{ $_->[0] }{ $_->[1] }
Pak => sub { pak_look($pak_ref) }, # $cells->{ pack "ii", $p->[0],
+$p->[1] }
St2 => sub { st2_look($st2_ref) }, # $cells->{ join(':', @$p) }
St3 => sub { st3_look($st3_ref) }, # $cells->{ $str } # optimized
Str => sub { str_look($str_ref) }, # $cells->{ $p->[0] .':'. $p->[1
+] }
};
Results from CentOS 7.3 VM running Perl 5.16.3.
Regards, Mario |