Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"

Re: each or keys?

by chromatic (Archbishop)
on Oct 11, 2000 at 02:44 UTC ( #36146=note: print w/replies, xml ) Need Help??

in reply to each or keys?

Try it this way:
#!/usr/bin/perl -w use Benchmark; use strict; use integer; my %top_hash; for (my $i = 0; $i < 1000; $i++) { $top_hash{$i} = $i; } sub e { my $total = 0; my %hash = %top_hash; while (my($k, $v) = each %hash) { $total += $v; last if $total > 500; } } sub k { my $total = 0; my %hash = %top_hash; foreach my $k (keys %hash) { my $v = $hash{$k}; $total += $v; last if $total > 500; } } timethese(500, { 'each' => \&e, 'keys' => \&k });
Why copy the hash? My guess is that there's an internal optimization going on the first time each is called. If you copy the old hash in every time, that optimization won't take place on the hash you're passing in to both subs.

Of course, you might print out the first ten elements of each and see if they're coming out in the same order. If the first two values you get out of each are both above 250, you'll jump out right there. If it takes a dozen from keys to get over 500, you have to go through the loop six more times. (I don't think that's likely, but it's good to check these kinds of assumptions before benchmarking).

My results for the revised code (500 iterations because copying a 1000-element hash is pretty time consuming):

Benchmark: timing 500 iterations of each, keys... each: 4 wallclock secs ( 3.77 usr + 0.01 sys = 3.78 CPU) keys: 5 wallclock secs ( 4.85 usr + 0.00 sys = 4.85 CPU)

Replies are listed 'Best First'.
RE: Re: each or keys?
by merlyn (Sage) on Oct 11, 2000 at 03:42 UTC
    Copying the hash means that keys and values might come out in different orders, and since you're quitting when the total reaches a certain point, you have a bogus benchmark.

    I suggest setting all the values to be the same and rerunning the benchmarks.

    -- Randal L. Schwartz, Perl hacker

      Good call

      Benchmark: running each, keys, each for at least 10 CPU seconds...
            each: 11 wallclock secs (10.51 usr +  0.00 sys = 10.51 CPU) @ 417.32/s (n=4386)
            keys: 11 wallclock secs (10.53 usr +  0.00 sys = 10.53 CPU) @ 286.89/s (n=3021)
            Rate keys each
      keys 287/s   -- -31%
      each 417/s  45%   --

      This is with $top_hash{$i} = 50; and cmpthese(-10, { 'each' => \&e, 'keys' => \&k }); and otherwise the same as above.

      $you = new YOU;
      honk() if $you->love(perl)

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://36146]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (5)
As of 2021-04-13 06:44 GMT
Find Nodes?
    Voting Booth?

    No recent polls found