Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Re: Algorithm Efficiency vs. Specialized Hardware?

by Aighearach (Initiate)
on Jun 20, 2000 at 14:10 UTC ( [id://18963]=note: print w/replies, xml ) Need Help??


in reply to Algorithm Efficiency vs. Specialized Hardware?

Benchmark: timing 1000000 iterations of Grep, Max, Ternary...
      Grep:  4 wallclock secs ( 3.02 usr +  0.00 sys =  3.02 CPU) @ 331125.83/s (n=1000000)
       Max:  7 wallclock secs ( 5.79 usr +  0.00 sys =  5.79 CPU) @ 172711.57/s (n=1000000)
   Ternary:  5 wallclock secs ( 5.72 usr +  0.00 sys =  5.72 CPU) @ 174825.17/s (n=1000000)

Which is very different than what I had before. To shed some light on this, let me first point out that the code above is almost but not quite the code I got my previous results from.

The only difference is, my code put each snippet to be benchmarked inside a sub, and then game Benchmark the function calls. I did this because I thought it more acurately reflected real-world max() usage, but this is certainly not true for all programs. Also different is that I changed my to our, so as not to change the function calls or add use vars. Would this make any difference speed difference? I know our is new to 5.6.0, and I am already loving it, but I don't know it's internals.

Now I'll take Russ's code given above and just make that one change. The function calls are SO expensive compared to the rest of the code, that I will turn down the iterations to 10_000, but we will see it take much, much longer. Here is the code:

#!/usr/bin/perl -w use strict; our $now = 8; our %url = ( monday => { @{[map(($_,1), (1..1000))]} } ); use Benchmark; timethese(10000, { Grep => q{ Grep(); }, Ternary => q{ Ternary(); }, Max => q{ Max(); } }); sub Grep { $now = (sort grep {$_ <= $now} keys %{$url{'monday'}})[-1]; } sub Ternary { $now = ($now < $_ && $_ < 8 ? $_ : $now) for keys %{$url{'monday'} +}; } sub Max { foreach ( keys %{$url{'monday'}} ) { $now = $_ if $_ > $now }; }

And the results:

Benchmark: timing 10000 iterations of Grep, Max, Ternary...
      Grep: 72 wallclock secs (68.98 usr +  0.00 sys = 68.98 CPU) @ 144.97/s (n=10000)
       Max: 64 wallclock secs (60.01 usr +  0.00 sys = 60.01 CPU) @ 166.64/s (n=10000)
   Ternary: 66 wallclock secs (63.24 usr +  0.01 sys = 63.25 CPU) @ 158.10/s (n=10000)

And so this is more consistant with my earlier resutls.

Platform is an AMD K6-II/400 128megs SDRAM, running linux 2.2.12 and perl 5.6.0.

I really don't understand these results. I understand that function calls are very, very expensive( the reason OO is often slow; accessor methods vs lookups ), but I don't understand why the proportions are different. Why doesn't the function call add the same amount of proc time for each call? Or is there something else?

Paris Sinclair    |    4a75737420416e6f74686572
pariss@efn.org    |    205065726c204861636b6572
I wear my Geek Code on my finger.

Replies are listed 'Best First'.
RE:(2) Algorithm Efficiency (function overhead)
by Russ (Deacon) on Jun 21, 2000 at 00:35 UTC
    aighearach, I saw the same thing, but forgot to post anything about it. Thank you.

    I wonder about this as well. I suspected it was the profiler causing the extra overhead, but your results show it happening with just Benchmark. I have run it this way myself and found similar results.

    This is funny. I "preach" to co-workers to forget their 'C' days, and ignore performance. "Perl is about programmer efficiency, not CPU efficiency," I say. Now, I am fascinated with this discussion, which is all about esoteric trivia of Perl efficiency.

    :-)

    Russ

      No, it's not the extra weight of the subroutine calls, although sub calls do cause more overhead. What's causing this is what I mentioned earlier: you have scoping problems. None of the code you're benchmarking is actually using a valid value for either %url or $now. So your results are completely bogus.

      The valid results are those that use a properly scoped variable. Aighearach's code did this, though I'm not sure it did so intentionally.

      You can accomplish this by declaring your vars as package globals:

      use vars qw/$now %url/; $now = 8; %url = ( monday => { @{[map(($_,1), (1..1000))]} } );
      This gives valid results.
      Benchmark: timing 1000 iterations of Grep, Max, Ternary... Grep: 6 wallclock secs ( 5.49 usr + 0.00 sys = 5.49 CPU) Max: 5 wallclock secs ( 5.81 usr + 0.00 sys = 5.81 CPU) Ternary: 7 wallclock secs ( 6.42 usr + 0.00 sys = 6.42 CPU)

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (6)
As of 2024-03-28 22:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found