in reply to Foreach for array pruning?
Updated conclusion:
You can save some ram (assuming you haven't got any to spare) at a penalty of 10% runtime.
my @array = 1 .. 1_000_000; ## Note the above doubles mem. consumption. ## Half of which is immediately availble to the rest of the program. # Ripple the good values through the array my( $s, $d ); for( $s = $d = 0; $s < @array; $d++, $s++ ) { $array[ $s ] %2 and $s++;; $array[ $d ] = $array[ $s ]; }; # and truncate it. $#array = --$d;
Memory test code.
#! perl -slw use strict; our $SIZE ||= 1_000_000; # Don't build the test array by assigning a list # cos that doubles the memory consumption which # then serves to conseal the extra consumed by the grep my @array; push @array, $_ for 1 .. $SIZE; printf 'Check ram before ripple'; <STDIN>; #@array = grep not ($_ % 2), @array; my( $s, $d ); for( $s = $d = 0; $s < @array; $d++, $s++ ) { $array[ $s ] %2 and $s++, $array[ $d ] = $array[ $s ]; }; $#array = --$d; printf 'Check ram after ripple'; <STDIN>; die 'M_S: Mismatch:', scalar @array, " @array[ 0, -1 ]" unless @array == $SIZE / 2 and "@array[ 0, -1 ]" eq "2 $SIZE"; __END__ P:\test>371457-mem Check ram before grep 21844 kb Check ram after grep 35856 kb P:\test>371457-mem Check ram before ripple 21,844 kb Check ram after ripple 21,860 kb
Benchmark
#! perl -slw use strict; use Benchmark qw[ cmpthese ]; our $SIZE ||= 1000; our $DEBUG; cmpthese( 5, { simple_grep => q[ my @array = 1 .. $SIZE; @array = grep not ($_ % 2), @array; die 'S_G: Mismatch:', scalar @array, " @array[ 0, -1 ]" unless @array == $SIZE / 2 and "@array[ 0, -1 ]" eq "2 $SI +ZE"; ], splice_for => q[ my @array = 1 .. $SIZE; $array[ $_ ] % 2 and splice @array, $_, 1 for reverse 0 .. $#a +rray; die 'S_F: Mismatch:', scalar @array, " @array[ 0, -1 ]" unless @array == $SIZE / 2 and "@array[ 0, -1 ]" eq "2 $SI +ZE"; ], move_splice => q[ my @array = 1 .. $SIZE; my( $s, $d ); for( $s = $d = 0; $s < @array; $d++, $s++ ) { $array[ $s ] %2 and $s++, $array[ $d ] = $array[ $s ]; }; $#array = --$d; die 'M_S: Mismatch:', scalar @array, " @array[ 0, -1 ]" unless @array == $SIZE / 2 and "@array[ 0, -1 ]" eq "2 $SI +ZE"; ], }); __END__ P:\test>371457 -SIZE=100000 (warning: too few iterations for a reliable count) Rate splice_for move_splice simple_grep splice_for 0.798/s -- -94% -94% move_splice 12.3/s 1440% -- -8% simple_grep 13.3/s 1571% 9% -- P:\test>371457 -SIZE=2000000 ## splice_for removed from test. s/iter move_splice simple_grep move_splice 1.66 -- -8% simple_grep 1.52 9% --
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Foreach for array pruning? (Updated)
by spandox (Novice) on Jul 02, 2004 at 21:43 UTC | |
by BrowserUk (Patriarch) on Jul 02, 2004 at 22:34 UTC | |
by spandox (Novice) on Jul 03, 2004 at 05:02 UTC | |
by duff (Parson) on Jul 02, 2004 at 21:52 UTC |