use warnings; use strict; use feature 'say'; use Time::HiRes 'time'; srand( 1 ); my $n = 2e3; my @input = map int rand 1e5, 1 .. $n; my ( $check1, $check2 ); { # original code my $t = time; my @max; push @max, ( sort { $b <=> $a } @input )[ 0 ]; my @sums = @input; for my $i ( 1 .. $n - 1 ){ my $max = -~0; for my $j ( $i .. $n - 1 ){ # HOT-SPOT { ( $sums[ $j - $i ] += $input[ $j ] ) > $max and $max = $sums[ $j - $i ]; # HOT-SPOT } } push @max, $max; } say time - $t; $check1 = pack 'I*', @max; } { # PDL my $t = time; use PDL; use PDL::NiceSlice; my $sums = zeroes long, scalar @input; my $vec = pdl long, \@input; my @max = map $sums( 0 : -$_ - 1 ) -> inplace -> plus( $vec( $_ : -1 ), 0 ) -> maximum , 0 .. $#input; say time - $t; $check2 = pack 'I*', @max; } use Test::More; is $check1, $check2; done_testing; __END__ 0.148595094680786 0.0387320518493652 ok 1 1..1 14.5055229663849 0.759373903274536 ok 1 1..1