Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Re: Ref to hash entries are faster?

by GrandFather (Saint)
on Nov 29, 2006 at 21:12 UTC ( [id://586822]=note: print w/replies, xml ) Need Help??


in reply to Ref to hash entries are faster?

If you wish to ignore Tanktalus's good advice and sweat the small stuff then a benchmark gives an answer. Normal benchmark caveats apply of course - like the benchmark may not indicate anything at all about your particular situation.

use strict; use warnings; use Benchmark qw(cmpthese); use constant kHalfMax => 509; # Must be odd my %Contracts = (1..4 * kHalfMax); # kHalfMax * 2 key/value pairs my $key = kHalfMax; cmpthese (-1, { lookup => \&lookup, refit => \&refit, } ); sub lookup { return if $Contracts{$key} == 1; return if $Contracts{$key} == 1; return if $Contracts{$key} == 1; return if $Contracts{$key} == 1; return if $Contracts{$key} == 1; return if $Contracts{$key} == 1; return if $Contracts{$key} == 1; return if $Contracts{$key} == 1; } sub refit { my $ref = \$Contracts{$key}; return if $$ref == 1; return if $$ref == 1; return if $$ref == 1; return if $$ref == 1; return if $$ref == 1; return if $$ref == 1; return if $$ref == 1; return if $$ref == 1; }

Result:

Rate lookup refit lookup 443125/s -- -32% refit 648621/s 46% --

Note that the result is somewhat sensitive to the number of key/value pairs in the hash. 46% is about the largest difference I've seen.

Note too that at about 200 nano-seconds per access this tweak is unlikely to make much difference to most applications. Code clarity would be a much more important consideration!


DWIM is Perl's answer to Gödel

Replies are listed 'Best First'.
Re^2: Ref to hash entries are faster?
by ikegami (Patriarch) on Nov 29, 2006 at 23:29 UTC
    Not a fair comparison. You're creating an entirely new SV every time, whereas the OP was using an existing ref.
    $Contracts{$key}[STATE]
    vs
    my $r = $Contracts{$key}; $r->[STATE]
    is not similar to
    $Contracts{$key}
    vs
    my $r = \$Contracts{$key}; $$r

    Update:

    My benchmark:

    use strict; use warnings; use Benchmark qw( cmpthese ); use constant NUM_KEYS => $ARGV[0]; use constant NUM_ACCESSES => $ARGV[1]; use constant TEST_TIME => $ARGV[2]; our %contracts = map { $_ => [ 0 ] } 1 .. NUM_KEYS; my $lookup = ' foreach (keys %contracts) { _____ } '; $lookup =~ s/_____/'$a = $contracts{$_}[0];' x NUM_ACCESSES/e; my $refit = ' foreach (keys %contracts) { my $r = $contracts{$_}; _____ } '; $refit =~ s/_____/'$a = $r->[0];' x NUM_ACCESSES/e; cmpthese(TEST_TIME, { lookup => $lookup, refit => $refit, });
    My results:
    >perl 586841.pl 500 4 -5 Rate lookup refit lookup 1060/s -- -4% refit 1101/s 4% -- >perl 586841.pl 500 4 -5 Rate lookup refit lookup 1053/s -- -5% refit 1105/s 5% -- >perl 586841.pl 500 6 -5 Rate lookup refit lookup 772/s -- -11% refit 869/s 13% -- >perl 586841.pl 500 6 -5 Rate lookup refit lookup 775/s -- -11% refit 873/s 13% -- >perl 586841.pl 500 10 -5 Rate lookup refit lookup 496/s -- -19% refit 614/s 24% -- >perl 586841.pl 500 10 -5 Rate lookup refit lookup 499/s -- -19% refit 613/s 23% --

    Verdict: It's a fruitful optimization, but it's not ground breaking.

      Your benchmark is including the loop overhead - which is appropriate for "real" code, but dilutes the difference between the two access methods. Altering the appropriate parts of your code to:

      my $lookup = ' _____ '; $lookup =~ s/_____/'$a = $contracts{1}[0];' x NUM_ACCESSES/e; my $refit = ' my $r = $contracts{1}; _____ '; $refit =~ s/_____/'$a = $r->[0];' x NUM_ACCESSES/e;

      and using your last test set I get:

      Rate lookup refit lookup 245666/s -- -32% refit 360597/s 47% --

      which is double the difference shown with the loop overhead included, and is comparable with the result from my benchmark.

      Ain't benchmarks fun, almost as good as statictics! :-D


      DWIM is Perl's answer to Gödel
Re^2: Ref to hash entries are faster?
by Wiggins (Hermit) on Nov 29, 2006 at 21:28 UTC
    This is the real answer. 46% faster. 200 nanos is 200 more than 0.

    I am doing some network monitoring on a 100Mb network. Sharing CPU with the real application (customer too cheap for a dedicated monitoring box). At least 2 threads locking either the total hash, or an element of the hash. I have to minimize the lockout periods to maximize the chance of keeping up with the data stream.

    Also learned about the benchmark module. Thanks

    As to the spelling, This is modified code; I hadn't tried the reference to element itself, just winged it for the question.

    Thanks to all....

      Hmmm. Consider the following:

      use strict; use warnings; use Benchmark 'cmpthese'; use constant MAX => 520; my %contracts = ( 1 .. 2 * MAX ); cmpthese ( -1, { lookup => \&lookup, refit => \&refit, } ); sub lookup { for ( keys %contracts ) { return if $contracts{$_} == MAX; } } sub refit { for ( keys %contracts ) { my $ref = \$contracts{$_}; return if $$ref == MAX; } }

      Output (on my machine):

      Rate refit lookup refit 4263/s -- -21% lookup 5407/s 27% --

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others learning in the Monastery: (1)
As of 2024-04-24 15:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found