Um, I guess it helps if you know how to use qr// properly. You don't write /$qr/ if you want it fast, you write $qr!

I get qr// faster than even /o. Though, your benchmark is testing such micro operations that the results can be rather unstable. The most "likely looking" result I got (early on) was:

Rate Without /o With /o With qr Without /o 42725/s -- -26% -39% With /o 57636/s 35% -- -18% With qr 70185/s 64% 22% --
But a more typical result was:
Rate 2// 2/o 1// 1/o 1qr 2qr 2// 31.4/s -- -0% -0% -1% -25% -26% 2/o 31.5/s 0% -- -0% -0% -25% -25% 1// 31.6/s 0% 0% -- -0% -25% -25% 1/o 31.6/s 1% 0% 0% -- -25% -25% 1qr 41.9/s 33% 33% 33% 33% -- -1% 2qr 42.2/s 34% 34% 34% 34% 1% --
Yes, that's right, /o was so close that it even ran slower than // on occasion.

Note that I didn't change any of the code in the subroutines being benchmarked between these two runs (I did change the data used several times, but even other runs with the same data never gave me results very similar to that first result above). It is just that Benchmark has to do some interesting work to try to measure such micro operations and so can easily show differences of around 20% between successive runs of identical code. That is why I usually make sure I have the benchmarking code run each case twice (otherwise you are rather likely to give a 20% disadvantage to the case that gets run first, for example).

Also, always verify that all of your benchmarked cases are doing the same thing:

Without /o:2200 With /o:2200 With qr:2200

So I stand by my assertion that you should never use /o!

                - tye
#!/usr/bin/perl -w use strict; use Benchmark qw( cmpthese ); chomp( my @words = <DATA> ); push @words, map $_ x 100, @words; for( @words ) { if( s/ /0/g ) { s/0/ /; $_= reverse $_; } } seek DATA, 0, 0; push @words, grep chomp, <DATA>; @words= ( @words ) x 100; my $alpha = '[a-zA-Z]'; my $alnum = '[a-zA-Z0-9]'; my $qr= qr/^$alpha$alnum+$/; print 'Without /o:' => testsub(), $/, 'With /o:' => testsubo(), $/, 'With qr:' => testsubqr(), $/; cmpthese( -3, { '1//' => \&testsub, '1/o' => \&testsubo, '1qr' => \&testsubqr, '2//' => \&testsub, '2/o' => \&testsubo, '2qr' => \&testsubqr, }); sub testsub { my $count = 0; foreach (@words) { $count++ if(/^$alpha$alnum+$/); } return $count; } sub testsubo { my $count = 0; foreach (@words) { $count++ if(/^$alpha$alnum+$/o); } return $count; } sub testsubqr { my $count = 0; foreach (@words) { $count++ if $_ =~ $qr; } return $count; } __DATA__ include the real test data or code to generate it when posting benchmarks

In reply to Re^2: Never (qr//) by tye
in thread Never-to-use Perl features? by Juerd

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.