This Benchmark exhibits some of the same problems I discussed in Re: Re: Craftier. In particular, @foo is a lexical variable which is not accessible in the Benchmark package, where your code snippets are being compiled. All of your snippets are working on an empty @foo. (You might have noticed that, despite the three print statements, your code never actually printed anything.)

Since you're passing quoted strings, all you're really testing is the time to compile each snippet, which is not a very useful measure. Also note that the third snippet omitted $_ in the print statement.

Here's an improved benchmark.

#!/usr/local/bin/perl -w use strict; use Benchmark; my @foo = map {int rand 3} 1..100; open(OUT, ">bm.out") or die "$!\n"; # Note: bm.out will be a large file when this is done. :) timethese(-10, { mod => sub { for (@foo) { print OUT "$_" if $_; } print OUT "\n"; }, block => sub { for (@foo) { if ($_) { print OUT "$_"; } } print OUT "\n"; }, and => sub { for (@foo) { $_ and print OUT "$_"; } print OUT "\n"; }, } ); __END__ Benchmark: running and, block, mod, each for at least 10 CPU seconds.. +. and: 3554.42/s block: 3530.86/s mod: 3511.90/s
With a re-structured benchmark, all three options are roughly equivalent, as you would expect.

However, there's also a lot of extra code in each snippet, which could be obscuring actual differences between the code we're really trying to test. In particular, I'd expect the print to be slow relative to the rest of the code.

Here's another benchmark.

#!/usr/local/bin/perl -w use strict; use Benchmark; my $foo = 0; # $foo will be toggled between true and false my $x; timethese(-10, { mod => sub { $x = 1 if $foo ^= 1 }, block => sub { if ($foo ^= 1) { $x = 1 } }, and => sub { $foo ^= 1 and $x = 1 }, } ); __END__ Benchmark: running and, block, mod, each for at least 10 CPU seconds.. +. and: 233020.67/s block: 230307.69/s mod: 234463.20/s Benchmark: running and, block, mod, each for at least 10 CPU seconds.. +. and: 237002.40/s block: 236647.46/s mod: 226841.12/s
This benchmark also shows no significant difference between the three forms.

We can draw two conclusions from these results: first, that it is important to have a well-constructed benchmark; and second, that the three forms of if/then are equivalent in terms of efficiency.


In reply to Re: Re: Loops and speed by chipmunk
in thread Loops and speed by damian1301

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.