You went to a bit of trouble to analyse this, so I thought I'd repay you (hey, I work in QA all day -- test methodology is something I should know about!). At the end of this post I show that your test results are valid, but my conclusion is that your method is wrong. In your test, the pre-compiled optimized expression is contained in a variable which means it has to be pushed onto the stack and interpolated. The non-optimized expression was inline. So I changed a few things to make this more consistent and got different results. I put the non-optimized regular expressions into variables to keep the test consistent (so it has to push a variable onto the stack and interpolate it and all that jazz).

Here's the code:


#!/usr/bin/perl
no warnings;
use strict;
use Benchmark qw(cmpthese);

$::string = "foofoo catbar";
$::re_foobOrNowt     = qr/(foob|)foofoo/o;
$::re_foob0or1        = qr/(foob)?foofoo/o;
$::foobOrNowt = qr/(foob|)foofoo/;
$::foob0or1   = qr/(foob)?foofoo/;

#study $::string; print 'After studying the searched string'.$/;
cmpthese( 1000000, {
    foobOrNowt    => 'if ($string =~ $::foobOrNowt) { };',
    foob0or1    => 'if ($string =~ $::foob0or1) { };',
    c_foobOrNowt=> 'if ($string =~ $::re_foobOrNowt) { };',
    c_foob0or1    => 'if ($string =~ $::re_foob0or1  ) { };',
});
Here's the results:

ddouville@linuxdld:~> ./test2.pl 
Benchmark: timing 1000000 iterations of c_foob0or1, c_foobOrNowt, foob0or1, foobOrNowt...
c_foob0or1:  3 wallclock secs ( 1.92 usr +  0.00 sys =  1.92 CPU) @ 520833.33/s (n=1000000)
c_foobOrNowt:  2 wallclock secs ( 1.73 usr +  0.00 sys =  1.73 CPU) @ 578034.68/s (n=1000000)
  foob0or1:  1 wallclock secs ( 1.96 usr +  0.00 sys =  1.96 CPU) @ 510204.08/s (n=1000000)
foobOrNowt:  2 wallclock secs ( 1.99 usr +  0.02 sys =  2.01 CPU) @ 497512.44/s (n=1000000)
                 Rate   foobOrNowt     foob0or1   c_foob0or1 c_foobOrNowt
foobOrNowt   497512/s           --          -2%          -4%         -14%
foob0or1     510204/s           3%           --          -2%         -12%
c_foob0or1   520833/s           5%           2%           --         -10%
c_foobOrNowt 578035/s          16%          13%          11%           --
Code:

#!/usr/bin/perl
no warnings;
use strict;
use Benchmark qw(cmpthese);

$::string = "foofoo catbar";
$::re_foobOrNowt     = qr/(foob|)foofoo/o;
$::re_foob0or1        = qr/(foob)?foofoo/o;
$::foobOrNowt = qr/(foob|)foofoo/;
$::foob0or1   = qr/(foob)?foofoo/;

#study $::string; print 'After studying the searched string'.$/;
cmpthese( 1000, {
    foobOrNowt    => 'for (1..10000) { if ($string =~ $::foobOrNowt) { };}',
    foob0or1    => 'for (1..10000) { if ($string =~ $::foob0or1) { };}',
    c_foobOrNowt=> 'for (1..10000) { if ($string =~ $::re_foobOrNowt) { };}',
    c_foob0or1    => 'for (1..10000) { if ($string =~ $::re_foob0or1  ) { };}',
});
Results

ddouville@linuxdld:~> ./test2.pl
Benchmark: timing 1000 iterations of c_foob0or1, c_foobOrNowt, foob0or1, foobOrNowt...
c_foob0or1: 16 wallclock secs (15.97 usr +  0.00 sys = 15.97 CPU) @ 62.62/s (n=1000)
c_foobOrNowt: 16 wallclock secs (16.25 usr +  0.00 sys = 16.25 CPU) @ 61.54/s (n=1000)
  foob0or1: 17 wallclock secs (16.34 usr +  0.00 sys = 16.34 CPU) @ 61.20/s (n=1000)
foobOrNowt: 17 wallclock secs (17.32 usr +  0.00 sys = 17.32 CPU) @ 57.74/s (n=1000)
               Rate   foobOrNowt     foob0or1 c_foobOrNowt   c_foob0or1
foobOrNowt   57.7/s           --          -6%          -6%          -8%
foob0or1     61.2/s           6%           --          -1%          -2%
c_foobOrNowt 61.5/s           7%           1%           --          -2%
c_foob0or1   62.6/s           8%           2%           2%           --
My tests show a performance increase in the compiled versions.

Finally, here's your initial test (unaltered), run on my own machine for base-line comparison: ddouville@linuxdld:~> ./test2.pl Benchmark: timing 1000000 iterations of c_foob0or1, c_foobOrNowt, foob0or1, foobOrNowt... c_foob0or1: 2 wallclock secs ( 1.92 usr + 0.00 sys = 1.92 CPU) @ 520833.33/s (n=1000000) c_foobOrNowt: 1 wallclock secs ( 1.78 usr + 0.00 sys = 1.78 CPU) @ 561797.75/s (n=1000000) foob0or1: 0 wallclock secs ( 1.33 usr + 0.00 sys = 1.33 CPU) @ 751879.70/s (n=1000000) foobOrNowt: 1 wallclock secs ( 1.34 usr + 0.00 sys = 1.34 CPU) @ 746268.66/s (n=1000000) Rate c_foob0or1 c_foobOrNowt foobOrNowt foob0or1 c_foob0or1 520833/s -- -7% -30% -31% c_foobOrNowt 561798/s 8% -- -25% -25% foobOrNowt 746269/s 43% 33% -- -1% foob0or1 751880/s 44% 34% 1% -- These test results agree with your test results, supporting that your results are correct for the test you performed.


In reply to Re: Re: Difference between (foo|) and (foo)? by Anonymous Monk
in thread Difference between (foo|) and (foo)? by Derek2

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.