If, based on your answers in this thread, ultimate goal is better speed after all (and not mysterious slow-downs on every 10th run, about which I have nothing to add), then as usual in case of large arrays, use PDL;. Second pair of results are for 10x $n.
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