Hi
the following code was intended to show to my colleagues that hash-slices are faster than maps.
What's surprising me is that a variant with explicit keys is always faster than using a constant list.
And the latter is slower than using a variable array!!!
Please note that B::Deparse doesn't show any code difference (haven't run it through B::Concise yet)
What am I doing wrong?
-*- mode: compilation; default-directory: "d:/Users/LanX/vm_share/pm/"
+ -*-
Compilation started at Wed Mar 13 13:03:10
C:/Perl_524/bin\perl.exe d:/Users/LanX/vm_share/pm/benchmark_slice.pl
+
Smartmatch is experimental at d:/Users/LanX/vm_share/pm/benchmark_slic
+e.pl line 60.
hash %h: {
xxxxa => 12345,
xxxxb => 12346,
xxxxc => 12347,
xxxxd => 12348,
xxxxe => 12349,
xxxxf => 12350,
}
Rate map_const map_var slice_const slice_var slic
+e_explicit
map_const 326753/s -- -36% -86% -87%
+ -88%
map_var 511706/s 57% -- -78% -79%
+ -82%
slice_const 2284993/s 599% 347% -- -6%
+ -18%
slice_var 2423666/s 642% 374% 6% --
+ -14%
slice_explicit 2802527/s 758% 448% 23% 16%
+ --
ok 1 - slice_const
{
use warnings;
use strict;
no feature ':all';
use feature ':5.12';
join ',', @h{'xxxxa', 'xxxxb', 'xxxxc', 'xxxxd', 'xxxxe', 'xxxxf'}
+;
}
ok 2 - map_const
ok 3 - map_var
ok 4 - slice_var
ok 5 - slice_explicit
{
use warnings;
use strict;
no feature ':all';
use feature ':5.12';
join ',', @h{'xxxxa', 'xxxxb', 'xxxxc', 'xxxxd', 'xxxxe', 'xxxxf'}
+;
}
1..5
Compilation finished at Wed Mar 13 13:03:55
use 5.012;
use strict;
use warnings;
use Data::Dump qw/pp dd/;
use Benchmark qw( cmpthese ) ;
use Test::More;
use B::Deparse;
my $deparse = B::Deparse->new();
use constant SHOW_DEPARSE => 1;
my (@keys, @values, %h, $expected);
BEGIN {
my $n_keys = 6;
my ( $first_key, $first_value ) = ("xxxxa",12345);
push @keys, $first_key++ for 1.. $n_keys;
push @values, $first_value++ for 1.. $n_keys;
@h{@keys} = @values; # init hash
$expected = join ",", @values;
eval <<"__CODE__";
sub slice_explicit {
join ",", \@h{ qw/@keys/}
}
__CODE__
}
warn "hash %h: ", pp(\%h) ,"\n";
use constant LIST=>(@keys);
my @list= @keys;
my $h_subs =
{
map_var => sub{ join ",", map { $h{$_} } @list },
map_const => sub{ join ",", map { $h{$_} } LIST },
slice_var => sub{ join ",", @h{@list} },
slice_const => sub{ join ",", @h{LIST()} },
slice_explicit => \&slice_explicit,
}
;
cmpthese( -5, $h_subs );
# --- test validity
while ( my ($name,$sub) = each %$h_subs ) {
my $result = $sub->();
is($result, $expected, $name);
# --- show code
say $deparse->coderef2text($sub)
if SHOW_DEPARSE and $name ~~ [qw/slice_const slice_explicit/];
}
done_testing();
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.