http://www.perlmonks.org?node_id=257755


in reply to Re: Never
in thread Never-to-use Perl features?

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