#! perl -slw use strict; use Benchmark::Timer; use List::Util qw[ sum ]; use constant { ID => 0, DISCHARGE => 1, PRECIPITATION => 2 }; sub stdDev { my $ave = 0; $ave += $_ for @_; $ave /= @_; my $variance = sum( map +($_ - $ave)**2, @_ ) / @_; return sqrt $variance; } our $G ||= 100; our $N ||= 1e6; my $T = new Benchmark::Timer; my @data = map{ [ $_, rand 100, rand 10 ] } 1 .. $N; my $label = "Moving Std Dev: $G of $N items"; $T->start( $label ); $G--; my @stdDevs = map [], 1 .. $N - $G; for my $item ( 0 .. $#data - $G ) { @{ $stdDevs[ $item ] } = ( stdDev( map{ $_->[ DISCHARGE ] } @data[ $item .. $item + $G ] ) , stdDev( map{ $_->[ PRECIPITATION ] } @data[ $item .. $item + $G ] ) ); } $T->stop( $label ); $T->report; #printf "id:$_ StdDev(Discharge):$stdDevs[ $_ ][ 0 ] StdDev(Precipitation):$stdDevs[ $_ ][ 1 ]\n" for 0 .. $#stdDevs; __END__ C:\test>579883 -N=1e3 1 trial of Moving Std Dev: 100 of 1e3 items (323.326ms total) C:\test>579883 -N=1e4 1 trial of Moving Std Dev: 100 of 1e4 items (3.750s total) C:\test>579883 -N=1e5 1 trial of Moving Std Dev: 100 of 1e5 items (36.063s total) C:\test>579883 -N=1e6 1 trial of Moving Std Dev: 100 of 1e6 items (372.109s total)