use strict; use warnings; use Benchmark qw(cmpthese); sub algorithm { my $ref = shift; return (undef,undef,undef) if ! $ref; my @ary = @$ref; my ( $min, $max, $tot ); if (@ary % 2) { $min = $max = $tot = shift( @ary ); } else { ($min, $max) = ($ary[0] < $ary[1]) ? ($ary[0], $ary[1]) : ($ary[1], $ary[0]); $tot = $min + $max; splice( @ary, 0, 2 ); } while ( @ary ) { if ( $ary[0] < $ary[1] ) { $min = $ary[0] if ( $ary[0] < $min ); $max = $ary[1] if ( $ary[1] > $max ); } else { $min = $ary[1] if ( $ary[1] < $min ); $max = $ary[0] if ( $ary[0] > $max ); } $tot += $ary[0] + $ary[1]; splice( @ary, 0, 2 ); } return ( $min, $max, $tot / @$ref ); } sub simple { my $r = shift; if (@$r) { my ($min, $max, $tot) = ($r->[0]) x 3; for (@$r[ 1 .. $#{$r}]) { $min = $_ if $_ < $min; $max = $_ if $_ > $max; $tot += $_; } return ($min, $max, $tot / @$r); } return (undef, undef, undef) } my @nums = map { rand } ( 1 .. 1000 ); # verify they do the same thing! # print "simple: @{[simple(\@nums)]}\n"; # print "algorithm: @{[algorithm(\@nums)]}\n"; cmpthese(-1, { algorithm => sub { my @r = algorithm(\@nums) }, simple => sub { my @r = simple(\@nums) } }) #### Rate algorithm simple algorithm 1517/s -- -30% simple 2177/s 44% --