#!/usr/bin/perl use strict; use warnings; use Benchmark qw(cmpthese timethese); # Randomly generate a hash. my $bench_count = 8000; my $kcount = 150; my ($h1,$h2); $h1->{random_string(2+int(rand() * 15)) }++ for (1..$kcount); $h2->{random_string(2+int(rand() * 15)) }++ for (1..$kcount); print "Benchmarking non-matching hashes\n"; my $results = timethese($bench_count ,{ each_cmp=> sub { compare_each_keys( +$h1,$h2) }, diotalevi_cmp=> sub { compare_diota +levi_keys($h1,$h2) }, iter_cmp=> sub { compare_hash_keys( +$h1,$h2) } } ); cmpthese($results); # Now test when there is a match print "Benchmarking matching hashes\n"; $results = timethese($bench_count ,{ each_cmp=> sub { compare_each_keys( +$h1,$h1) }, diotalevi_cmp=> sub { compare_diota +levi_keys($h1,$h1) }, iter_cmp=> sub { compare_hash_keys( +$h1,$h1) } } ); cmpthese($results); sub compare_each_keys { my ($h1,$h2) = @_; return 0 if keys %$h1 != keys %$h2; while (my $k = each %$h1){ return 0 if ! exists $h2->{$k}; } return 1; } sub compare_diotalevi_keys { my ($h1,$h2) = @_; my $test; # A temporary variable for holding a result so it doesn' +t have to be recomputed. my @k1 = keys %$h1; my @k2 = keys %$h2; $test = @k1 <=> @k2 and return $test; for ( 0 .. $#k1 ) { $test = $k1[$_] cmp $k2[$_] and return $test; } return; } sub compare_hash_keys { my ($h1,$h2) = @_; my @k1 = sort keys %$h1; my @k2 = sort keys %$h2; return @k2 - @k1 if @k1 <=> @k2; for (0..$#k1) { return $k1[$_] cmp $k2[$_] if $k1[$_] cmp $k2[$_]; } 0; } sub random_string { my $length = shift || 2; my @chars = ('a'..'z','A'..'Z',0..9); join ('',map{ $chars[ rand() * @chars ] } (1..$length)); } __END__ Benchmarking non-matching hashes Benchmark: timing 8000 iterations of diotalevi_cmp, each_cmp, iter_cmp +... diotalevi_cmp: 9 wallclock secs ( 8.22 usr + 0.00 sys = 8.22 CPU) @ + 973.24/s (n=8000) each_cmp: 0 wallclock secs ( 0.20 usr + 0.00 sys = 0.20 CPU) @ 40 +000.00/s (n=8000) (warning: too few iterations for a reliable count) iter_cmp: 18 wallclock secs (15.24 usr + 0.00 sys = 15.24 CPU) @ 52 +4.93/s (n=8000) Rate iter_cmp diotalevi_cmp each_cmp iter_cmp 525/s -- -46% -99% diotalevi_cmp 973/s 85% -- -98% each_cmp 40000/s 7520% 4010% -- Benchmarking matching hashes Benchmark: timing 8000 iterations of diotalevi_cmp, each_cmp, iter_cmp +... diotalevi_cmp: 20 wallclock secs (11.76 usr + 0.03 sys = 11.79 CPU) @ + 678.54/s (n=8000) each_cmp: 10 wallclock secs ( 9.63 usr + 0.00 sys = 9.63 CPU) @ 83 +0.74/s (n=8000) iter_cmp: 18 wallclock secs (18.04 usr + 0.00 sys = 18.04 CPU) @ 44 +3.46/s (n=8000) Rate iter_cmp diotalevi_cmp each_cmp iter_cmp 443/s -- -35% -47% diotalevi_cmp 679/s 53% -- -18% each_cmp 831/s 87% 22% --
In reply to Re: Comparing all keys in a hash
by shotgunefx
in thread Comparing all keys in a hash
by rinceWind
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |