use strict; use warnings; use Benchmark qw(cmpthese); my @array = (1..10_000); # An array to be shuffled. $_ = int rand (52) for @array; # Rather then pass in a ref to the array, just shuffle the array in place. cmpthese( 10000, { 'BRANCH' => sub { my $i=@array; while($i--){ my $j=int rand(1+$i); next if $i==$j; ### This is the line being tested. @array[$i, $j]=@array[$j, $i] }}, 'WITHOUT' => sub { my $i=@array; while($i--){ my $j=int rand(1+$i); @array[$i, $j]=@array[$j, $i] }}, 'IFIDDLE' => sub { my $i=@array; while($i){ my $j=int rand($i--); @array[$i, $j]=@array[$j, $i] }}, 'MY_J_OUT' => sub { my $i=@array; my $j; while($i){ $j=int rand($i--); @array[$i, $j]=@array[$j, $i] }}, 'FOR_LOOP' => sub { my $j; $j = int rand ($_), @array[$_, $j] = @array[$j, $_] for reverse 1 .. $#array; }, 'BUK' => sub { my( $r, $t ); $r = $_ + rand( @array - $_ ), $t = $array[ $_ ], $array[ $_ ] = $array[ $r ], $array[ $r ] = $t for 0 .. $#array; }, } ); # Benchmark: timing 10000 iterations of BRANCH, BUK, FOR_LOOP, IFIDDLE, MY_J_OUT, WITHOUT... # BRANCH: 64 wallclock secs (62.72 usr + 0.00 sys = 62.72 CPU) @ 159.44/s (n=10000) # BUK: 62 wallclock secs (59.58 usr + 0.00 sys = 59.58 CPU) @ 167.85/s (n=10000) # FOR_LOOP: 55 wallclock secs (53.22 usr + 0.00 sys = 53.22 CPU) @ 187.91/s (n=10000) # IFIDDLE: 54 wallclock secs (52.61 usr + 0.00 sys = 52.61 CPU) @ 190.08/s (n=10000) # MY_J_OUT: 50 wallclock secs (46.81 usr + 0.00 sys = 46.81 CPU) @ 213.62/s (n=10000) # WITHOUT: 55 wallclock secs (53.11 usr + 0.00 sys = 53.11 CPU) @ 188.29/s (n=10000) # Rate BRANCH BUK FOR_LOOP WITHOUT IFIDDLE MY_J_OUT # BRANCH 158/s -- -4% -16% -16% -17% -27% # BUK 164/s 4% -- -12% -13% -13% -24% # FOR_LOOP 187/s 19% 14% -- -0% -1% -14% # WITHOUT 188/s 19% 14% 0% -- -1% -14% # IFIDDLE 190/s 20% 15% 1% 1% -- -13% # MY_J_OUT 218/s 38% 32% 16% 16% 15% --