I have decided to post this as a new SOPW question, because it is different (though related to) the question which spawned it.

Thanks to all who posted their results. I had no idea we would see 21 posts (so far). What a helpful and energetic crowd this is... :-)

I was benchmarking some code incorrectly. btrott pointed out that the code being timed was not "seeing" the variables I intended it to use.

He is absolutely right. I don't understand why, though. (Why it does what it does, not why btrott is right) :-)

perldoc Benchmark says of timethis (which timethese calls),

Simple test scripts to simulate Benchmark.pm's behavior work as I expect. In other words, the eval'ed code can see the package variables.

In Benchmark.pm, the runloop subroutine does basically this:

my $subcode = sub { for (1 .. $n) { local \$_; package $pack; $c;} } my $subref = eval $subcode; &$subref
where $n is the number of iterations, $pack is the caller's package and $c is the code to execute.

So, simulating Benchmark could look roughly like this:

package R; # Just to demonstrate a variable in another package my $R = 10; package main; # Just to prove we are "executing" in a different packag +e my $subcode = "sub { local \$_; package R; print $R}"; my $subref = eval $subcode; &$subref;
Executing this code will print 10. Reversing the packages (so $R is in main, and we execute the code in package R, but tell it to run in package main) also prints 10. Using only package main, it will still print 10. In other words, I have not found a way to make this code behave like Benchmark.

So, I don't yet understand why my original code doesn't access $now and %url. It clearly doesn't, but I don't know why.

Any takers? :-)

Russ

P.S. I have to assume I will be embarrassed at what I am missing, here, but please fire away.

P.P.S. Here are my results with the correct code. Grep is still faster than the other algorithms, so the original question still stands (how can Perl execute an O(N) plus an O(N log N) algorithm faster than a single O(N)?)

Benchmark: timing 1000 iterations of Grep, Max, Ternary... Grep: 20 wallclock secs (19.99 usr + 0.03 sys = 20.02 CPU) Max: 22 wallclock secs (21.69 usr + 0.03 sys = 21.72 CPU) Ternary: 22 wallclock secs (22.58 usr + 0.00 sys = 22.58 CPU)

P.P.P.S. Many kudos to aighearach, lhoward, btrott and many others for their good work helping me explore this issue. You have worked wonders toward satisfying my (insatiable?) curiosity.
Thank you


In reply to Benchmark.pm's scoping behavior by Russ

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.