Several problems:
- With just 6 comparisons & assignments being run; the overhead of two subroutine calls -- the one you wrapped your tests in and the one Benchmarks wraps those in internally -- becomes a significant factor in the tests.
Pass strings instead of subs to remove one layer of sub-call overhead; and allow benchmark to eval them into subroutines. (It's going to anyway!)
Use an internal loop multiplier to re-balance the test/overhead.
- By passing your args wrapped in anonymous arrays -- thus forcing the ternary to do 3 dereferences; and the clever to do 4 dereferences; whereas List::Util only does one -- you bias the tests strongly in List::Util's favour.
Most min() operations will operate on simple scalars so use those instead.
- (Minor.) There is little value in using different and big integers; they are all just IVs (or UVs) as far as the comparisons are concerned.
Test for differences in ordering (branch/no branch) by coding separate tests.
The upshot is that the ordering makes no consistent difference (Ie. it flip flops from run to run); and that the ternary is hands down winner for the two simple scalars, common case:
use strictures;
use Benchmark "cmpthese";
use List::Util "min"; # This is XS.
cmpthese -1, {
list_util_nb => q[ my( $x, $y ) = ( 0, 1 ); my $m = min( $x, $y
+) for 1 .. 1000; ],
ternary_nb => q[ my( $x, $y ) = ( 0, 1 ); my $m = $x < $y
+ ? $x : $y for 1 .. 1000; ],
clever_nb => q[ my( $x, $y ) = ( 0, 1 ); my $m = [ $x, $y
+ ]->[ $x <= $y ] for 1 .. 1000; ],
list_util_b => q[ my( $x, $y ) = ( 1, 0 ); my $m = min( $x, $y
+) for 1 .. 1000; ],
ternary_b => q[ my( $x, $y ) = ( 1, 0 ); my $m = $x < $y
+ ? $x : $y for 1 .. 1000; ],
clever_b => q[ my( $x, $y ) = ( 1, 0 ); my $m = [ $x, $y
+]->[ $x <= $y ] for 1 .. 1000; ],
};
__END__
C:\test>junk30
Rate clever_b clever_nb list_util_nb list_util_b ternar
+y_b ternary_nb
clever_b 1210/s -- -11% -67% -70% -
+79% -80%
clever_nb 1356/s 12% -- -63% -67% -
+76% -78%
list_util_nb 3694/s 205% 172% -- -9% -
+34% -40%
list_util_b 4062/s 236% 200% 10% -- -
+28% -33%
ternary_b 5630/s 365% 315% 52% 39%
+ -- -8%
ternary_nb 6107/s 405% 351% 65% 50%
+ 8% --
C:\test>junk30
Rate clever_nb clever_b list_util_b list_util_nb ternar
+y_b ternary_nb
clever_nb 1297/s -- -5% -68% -69% -
+75% -77%
clever_b 1372/s 6% -- -66% -67% -
+74% -75%
list_util_b 4078/s 214% 197% -- -3% -
+22% -27%
list_util_nb 4190/s 223% 205% 3% -- -
+20% -25%
ternary_b 5228/s 303% 281% 28% 25%
+ -- -6%
ternary_nb 5556/s 328% 305% 36% 33%
+ 6% --
List::Util::min() will obviously win in both speed and clarity for the min( @array ) case.
With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.