Try this. Much MUCH faster (The compare_each_keys).
#!/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% --


-Lee

"To be civilized is to deny one's nature."

In reply to Re: Comparing all keys in a hash by shotgunefx
in thread Comparing all keys in a hash by rinceWind

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.