http://qs1969.pair.com?node_id=11141584

in reply to Performance issue in the loop.

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

Replies are listed 'Best First'.
Re^2: Performance issue in the loop.
by etj (Chaplain) on Feb 27, 2022 at 03:53 UTC
Moar PDL!

Here's my tweak of vr's excellent code, for use in the perldl REPL, which doesn't feature the check, just does timing (and doesn't use strict because of the REPL), and uses "+=" instead of the wordier "->inplace->plus":

```\$n = 2e4;
@input = map int rand 1e5, 1 .. \$n;
\$sums = zeroes long, scalar @input;
\$vec  = pdl long, \@input;
with_time { my @max = map +(\$sums( 0 : -\$_ - 1 ) += \$vec( \$_ : -1 ))->
+maximum, 0 .. \$#input };