The entries are in, let's see how they fare in the much awaited Benchmark competition. ;-)
#!/usr/bin/perl use strict; use warnings; use Benchmark qw(:all); use Storable qw(dclone); my %HoH = ( elt1 => { A => 'ccc', B => 'ccc', C => 'ccc', }, elt2 => { A => 'ccc', C => 'ccc', D => 'ccc', B => 'ccc', }, elt3 => { A => 'ccc', E => 'ccc', C => 'ccc', }, ); sub perl_mouse { my %HoH = %{ dclone(shift) }; my %count; my $count = keys %HoH; while (my ($name, $hash) = each %HoH) { while (my ($key) = each %$hash) { $count{$key}++; } } while (my ($name, $hash) = each %HoH) { while (my ($key) = each %$hash) { delete $$hash{$key} unless $count{$key} == $count; } } } sub skeeve1 { my %HoH = %{ dclone(shift) }; my %count; my $count = scalar keys %HoH; for ( [ grep { $count != $count{$_} } map { ++$count{$_}; $_ } map { keys %{$HoH{$_}} } keys %HoH ] ) { for my $hash (values %HoH) { delete (@$hash{@$_}); } } } sub skeeve2 { my %HoH = %{ dclone(shift) }; my %count; my $count = scalar keys %HoH; my $k = [grep {$count == ++$count{$_}} map {keys %{$HoH{$_}}} keys %HoH]; for my $h (values %HoH) { %$h = map { $_, $h->{$_}} @$k; } } sub blazar { my %HoH = %{ dclone(shift) }; my @keys = keys %HoH; my %saw; for (@keys) { $saw{lc,}++ for keys %{ $HoH{$_} }; } for (@keys) { my $h = $HoH{$_}; $saw{lc,} < @keys and delete $h->{$_} for keys %$h; } } my $benchmark = timethese(5_000, { Perl_Mouse => sub { perl_mouse(\%HoH) }, Skeeve1 => sub { skeeve1(\%HoH) }, Skeeve2 => sub { skeeve2(\%HoH) }, Blazar => sub { blazar(\%HoH) }, } ); print "\n"; cmpthese($benchmark);
Behold the results...
Benchmark: timing 5000 iterations of Blazar, Perl_Mouse, Skeeve1, Skeeve2...
Blazar: 7 wallclock secs ( 3.61 usr + 1.36 sys = 4.97 CPU) @ 1006.04/s (n=5000)
Perl_Mouse: 7 wallclock secs ( 3.54 usr + 1.36 sys = 4.90 CPU) @ 1020.41/s (n=5000)
Skeeve1: 7 wallclock secs ( 3.48 usr + 1.35 sys = 4.83 CPU) @ 1035.20/s (n=5000)
Skeeve2: 8 wallclock secs ( 3.64 usr + 1.35 sys = 4.99 CPU) @ 1002.00/s (n=5000)
Rate Skeeve2 Blazar Perl_Mouse Skeeve1
Skeeve2 1002/s -- -0% -2% -3%
Blazar 1006/s 0% -- -1% -3%
Perl_Mouse 1020/s 2% 1% -- -1%
Skeeve1 1035/s 3% 3% 1% --
Update: modified the code and benchmark results, which were actually meaningless, thanks to ikegami's wise and knowledgeable advice. And as he rightly predicted, the difference between each method really isn't that huge.
In reply to Re: Common elements of a hash of hashes
by Fang
in thread Common elements of a hash of hashes
by Anonymous Monk
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |