And the code and results (on my box)
use 5.018001;
use warnings;
use Benchmark qw(:hireswallclock cmpthese );
use Test::More;
my $AoH;
my @cmpf = qw( map_map map_direct map_keys grep_map list_join );
my %test = map { $_ => \&$_ } "slice_join", @cmpf;
my $n_rec = 1;
for (1 .. 5) {
say "";
say "=== num of records is: ", $n_rec;
$AoH = create_data (1, $n_rec);
my $sj = [ sort &slice_join ];
is_deeply ([ sort $test{$_}->() ], $sj, "slice_join === $_") for @
+cmpf;
cmpthese (-3, \%test);
$n_rec *= 10;
}
done_testing;
sub list_join {
my %H;
%H = (%H, %$_) for @$AoH;
return keys %H;
} # list_join
sub slice_join {
my %H;
@H{keys %$_} = () for @$AoH;
return keys %H;
} # slice_join
sub grep_map {
my %seen;
return grep { !$seen{$_}++ } map { keys %$_ } @$AoH;
} # grep_map
sub map_map {
my %H = map { $_ => 1 } map { keys %$_ } @$AoH;
return keys %H;
} # map_map
sub map_direct {
my %H = (map %$_, @$AoH);
return keys %H
} # map_direct
sub map_keys {
my %H;
@H{map keys %$_, @$AoH} = ();
return keys %H
} # map_keys
sub create_data {
my ($density, $records) = @_;
my @AoH;
push @AoH, {map { rand 100 <= $density ? ("$_" => $_) : () } "A" .
+. "ZZ"}
for 1 .. $records;
return \@AoH;
}
=== num of records is: 1
ok 1 - slice_join === map_map
ok 2 - slice_join === map_direct
ok 3 - slice_join === map_keys
ok 4 - slice_join === grep_map
ok 5 - slice_join === list_join
Rate map_map map_direct list_join grep_map map_keys
+slice_join
map_map 754695/s -- -14% -17% -25% -42%
+ -43%
map_direct 882464/s 17% -- -3% -12% -32%
+ -33%
list_join 913980/s 21% 4% -- -9% -30%
+ -31%
grep_map 1002034/s 33% 14% 10% -- -23%
+ -24%
map_keys 1302904/s 73% 48% 43% 30% --
+ -2%
slice_join 1323455/s 75% 50% 45% 32% 2%
+ --
=== num of records is: 10
ok 6 - slice_join === map_map
ok 7 - slice_join === map_direct
ok 8 - slice_join === map_keys
ok 9 - slice_join === grep_map
ok 10 - slice_join === list_join
Rate list_join map_map map_direct grep_map slice_joi
+n map_keys
list_join 11635/s -- -80% -80% -84% -88
+% -89%
map_map 58659/s 404% -- 0% -18% -42
+% -44%
map_direct 58659/s 404% 0% -- -18% -42
+% -44%
grep_map 71323/s 513% 22% 22% -- -29
+% -32%
slice_join 100407/s 763% 71% 71% 41% -
+- -4%
map_keys 104260/s 796% 78% 78% 46% 4
+% --
=== num of records is: 100
ok 11 - slice_join === map_map
ok 12 - slice_join === map_direct
ok 13 - slice_join === map_keys
ok 14 - slice_join === grep_map
ok 15 - slice_join === list_join
Rate list_join map_direct map_map grep_map map_keys
+slice_join
list_join 161/s -- -97% -97% -98% -98%
+ -98%
map_direct 5584/s 3363% -- -3% -22% -45%
+ -46%
map_map 5748/s 3465% 3% -- -20% -44%
+ -44%
grep_map 7175/s 4350% 29% 25% -- -29%
+ -30%
map_keys 10175/s 6210% 82% 77% 42% --
+ -1%
slice_join 10288/s 6280% 84% 79% 43% 1%
+ --
=== num of records is: 1000
ok 16 - slice_join === map_map
ok 17 - slice_join === map_direct
ok 18 - slice_join === map_keys
ok 19 - slice_join === grep_map
ok 20 - slice_join === list_join
Rate list_join map_map map_direct grep_map map_keys
+slice_join
list_join 6.95/s -- -99% -99% -99% -99%
+ -99%
map_map 512/s 7267% -- -13% -48% -56%
+ -60%
map_direct 587/s 8341% 15% -- -41% -50%
+ -54%
grep_map 991/s 14157% 94% 69% -- -15%
+ -22%
map_keys 1172/s 16754% 129% 100% 18% --
+ -8%
slice_join 1273/s 18202% 148% 117% 28% 9%
+ --
=== num of records is: 10000
ok 21 - slice_join === map_map
ok 22 - slice_join === map_direct
ok 23 - slice_join === map_keys
ok 24 - slice_join === grep_map
ok 25 - slice_join === list_join
(warning: too few iterations for a reliable count)
Rate list_join map_map map_direct grep_map map_keys
+slice_join
list_join 0.597/s -- -98% -98% -99% -99%
+ -99%
map_map 31.0/s 5098% -- -9% -63% -65%
+ -73%
map_direct 34.2/s 5625% 10% -- -59% -62%
+ -70%
grep_map 84.0/s 13964% 171% 146% -- -6%
+ -27%
map_keys 89.4/s 14873% 188% 162% 6% --
+ -23%
slice_join 115/s 19235% 272% 238% 37% 29%
+ --
1..25
Enjoy, Have FUN! H.Merijn