in reply to Benchmarking instability
Your test is bad. Your code strings are being evaluated inside of Benchmark, oustside of $X and $Y's scope. Right now, you're using package variables $main::X and $main::Y, which are undefined.
Proof:
use strict; use warnings; use Benchmark 'cmpthese'; my $sz = ( shift || 10 ) - 4; my $X = 'N' . 'x' x $sz . '000'; my $Y = 'N' . 'x' x $sz . '001'; cmpthese( 1, { '?!X' => 'use strict; $X =~ /^N(?!.*00$).*$/', '?!Y' => 'use strict; $Y =~ /^N(?!.*00$).*$/', '?<!X' => 'use strict; $X =~ /^N.*(?<!00$)$/', '?<!Y' => 'use strict; $Y =~ /^N.*(?<!00$)$/', } ); __END__ Benchmark: timing 1 iterations of ?!X, ?!Y, ?<!X, ?<!Y... runloop unable to compile 'use strict; $X =~ /^N(?!.*00$).*$/': Global + symbol "$X" requires explicit package name at (eval 2) line 1. code: sub { for (1 .. 1) { local $_; package main; use strict; $X =~ / +^N(?!.*00$).*$/;} }
Fix:
use strict; use warnings; use Benchmark 'cmpthese'; my $sz = ( shift || 10 ) - 4; my $X = 'N' . 'x' x $sz . '000'; my $Y = 'N' . 'x' x $sz . '001'; print '# input length: ', length( $X ), $/; cmpthese( -1, { '?!X' => sub { scalar $X =~ /^N(?!.*00$).*$/ }, '?!Y' => sub { scalar $Y =~ /^N(?!.*00$).*$/ }, '?<!X' => sub { scalar $X =~ /^N.*(?<!00$)$/ }, '?<!Y' => sub { scalar $Y =~ /^N.*(?<!00$)$/ }, } );
The scalar shouldn't make a difference as long as you don't have captures. The real difference is the sub {} instead of ''. The subs now capture over $X and $Y. Using our $X and our $Y instead of my $X and my $Y would also have done the trick.
With the fixed code, it gives me the following, even when reversed:
X = Nxxxxxx000 Y = Nxxxxxx001 Rate ?<!X ?!Y ?!X ?<!Y ?<!X 327712/s -- -39% -56% -59% ?!Y 535499/s 63% -- -29% -34% ?!X 750772/s 129% 40% -- -7% ?<!Y 805492/s 146% 50% 7% --
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Benchmarking instability
by tlm (Prior) on Jun 06, 2005 at 20:24 UTC |