use Data::Dump qw(pp); sub kgb_hash { my %cells = map { pp($_) => undef } @points; \%cells; } { my @points_str; sub kgb_look { my $cells = shift; unless (@points_str) { for my $p (@points) { push @points_str, pp($p); } } for my $p (@points_str) { exists $cells->{$p} or die; } exists $cells->{'notfound'} and die; exists $cells->{'notfound2'} and die; exists $cells->{'notfound3'} and die; } } my $kgb_ref = kgb_hash(); ... timethese 200000, { Big => sub { big_look($big_ref) }, # $cells->{ ($p->[1] << 32) | ($p->[0] & 0xFFFFFFFF) } Kgb => sub { kgb_look($kgb_ref) }, # $cells->{ $str } # optimized 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] } };