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; #### #! 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'; ; #@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'; ; 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 #### #! 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 $SIZE"; ], splice_for => q[ my @array = 1 .. $SIZE; $array[ $_ ] % 2 and splice @array, $_, 1 for reverse 0 .. $#array; die 'S_F: Mismatch:', scalar @array, " @array[ 0, -1 ]" unless @array == $SIZE / 2 and "@array[ 0, -1 ]" eq "2 $SIZE"; ], 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 $SIZE"; ], }); __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% --