note
water
So I wanted to see how a sliding buffer compared to a simple push/shift. Maybe I implemented the sliding buffer in a slow way (suggestions?), but for my (likely poor) implementation, the simple push/shift is blazingly faster than the sliding buffer.
<p>
Did I blow the buffer implementation, or is native push/shift damn efficient? (probably both)
<code>
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);},
});
</code>
344087
344087