use strict; use Test::More 'no_plan'; use constant SIZE => 500; use Benchmark qw(:all); ################################################ # ROLL1: sliding buffer ################################################ { my ( $last, @x ); sub init1 { $last = SIZE - 1; @x = (undef) x SIZE; } sub roll1 { my ($val) = @_; $last = ( $last + 1 ) % SIZE; $x[$last] = $val; return \@x[&order]; } sub order { my $first = ( $last + 1 ) % SIZE; return ( $first .. SIZE - 1, 0 .. $last ); } sub dump1 { return join ( '-', @x[&order] ); } } ################################################ # ROLL2: simple push and shift ################################################ { my @x; sub init2 { @x = (undef) x SIZE; } sub roll2 { my ($val) = @_; push ( @x, $val ); shift @x; return \@x; } sub dump2 { return join ( '-', @x ); } } ################################################ # ensure both return the same results ################################################ for my $roll ( 5, 19, 786 ) { &init1; &init2; for ( my $i = 0 ; $i < $roll ; $i++ ) { my $val = rand; roll1($val); roll2($val); } is( dump1, dump2, "same results for $roll rolls" ); } ################################################ # benchmark them ################################################ timethese(100, { 'roll1' => sub { init1; roll1($_) for (1..10000);}, 'roll2' => sub { init2; roll2($_) for (1..10000);}, });