http://www.perlmonks.org?node_id=842907


in reply to Re^2: Optimizing a double loop
in thread Optimizing a double loop

You can still generate the full array of counts afterwards and have a speed benefit, because you only have to iterate once over the big array (as opposed to once per overlap in your current implementation).

Update:

Example code for obtaining the full array:

use strict; use warnings; my @a = (10, 15, -20, -30); my $highest = abs($a[-1]); my @full = (0) x ($highest + 1); # decrement all negative values by 1, otherwise # we would exclude the end points: for (@a) { $_-- if $_ < 0; } my $count = 0; for (0..$highest) { if (abs $a[0] == $_) { my $c = shift @a; if ($c > 0) { $count++; } else { $count--; } } $full[$_] += $count; } print join('', @full), "\n";

This assumes that there are never two values of same magnitude in the array, ie never exactly matching start- and endpoints. You can generalize it on your own :-)

Second update: I've just realized that the extension is very simple:

Instead of if (abs $a[0] == $_) write while (abs $a[0] == $_), and you're done.

Replies are listed 'Best First'.
Re^4: Optimizing a double loop
by roibrodo (Sexton) on Jun 03, 2010 at 12:51 UTC

    I'll give it a try. BTW, I will also need to sort the array (by abs values) now.

    UPDATE: There's no real to use $full[$_] += $count; instead of $full[$_] = $count;, is there? we can therefore also drop the initialization of @full, can't we?

      You're right on both accounts.

      I just used += because from reading your initial question I wasn't sure if you needed absolute values, or add them to an existing array.

        Thanks! Your suggestion proved to be a brilliant idea.
        I got a five-fold improvement in running time!
        Thanks so much! (and sorry for all the exclamation points, I'm just excited!)