in reply to Re^2: foreach array - delete current row ?
in thread foreach array - delete current row ?
There is a problem with your two routines that biases the benchmark in their favour.
My routines remove any value containing a 9; yours only keep those containing a 9.
Once you correct that (unless instead of if), you get a different set of numbers:
C:\test>1036622 -N=1e3 Rate grep build_new_array offset_copy for_splice edi +t_in_place grep 678/s -- -22% -27% -34% + -41% build_new_array 870/s 28% -- -6% -15% + -24% offset_copy 929/s 37% 7% -- -9% + -19% for_splice 1024/s 51% 18% 10% -- + -11% edit_in_place 1150/s 70% 32% 24% 12% + -- C:\test>1036622 -N=1e4 Rate for_splice grep offset_copy build_new_array edi +t_in_place for_splice 71.5/s -- -9% -11% -22% + -39% grep 78.7/s 10% -- -2% -14% + -33% offset_copy 80.6/s 13% 2% -- -12% + -31% build_new_array 91.3/s 28% 16% 13% -- + -22% edit_in_place 117/s 64% 49% 46% 29% + -- C:\test>1036622 -N=1e5 Rate for_splice grep build_new_array offset_copy edi +t_in_place for_splice 1.29/s -- -75% -83% -84% + -85% grep 5.12/s 296% -- -33% -35% + -42% build_new_array 7.68/s 494% 50% -- -3% + -14% offset_copy 7.88/s 509% 54% 3% -- + -11% edit_in_place 8.89/s 587% 74% 16% 13% + -- C:\test>1036622 -N=1e6 s/iter for_splice grep build_new_array offset_copy edi +t_in_place for_splice 77.9 -- -98% -98% -99% + -99% grep 1.39 5503% -- -14% -18% + -38% build_new_array 1.20 6379% 16% -- -5% + -28% offset_copy 1.14 6737% 22% 6% -- + -24% edit_in_place 0.868 8884% 60% 39% 31% + --
And actually, my original benchmark was also flawed -- or at least lazy -- in as much as it conflates the time taken to build the original array into the overall timings; which is unrealistic.
Correcting for that
: #! perl -slw use strict; use Benchmark qw[ cmpthese ]; our $N //= 1e3; our $I //= -1; our @as; @{ $as[ $_ ] } = 1 .. $N for 0 .. 4; cmpthese $I, { for_splice => q[ my $ar = $as[0]; $ar->[$_] =~ /9/ and splice @$ar, $_, 1 for reverse 0 .. $#$ar +; $I == 1 and print "0: ", "@$ar"; ], grep => q[ my $ar = $as[1]; @$ar = grep !/9/, @$ar; $I == 1 and print "1: ", "@$ar"; ], offset_copy => q[ my $ar = $as[2]; my $o = 0; for( 0 .. $#$ar ) { $ar->[$_-$o] = $ar->[$_]; $ar->[ $_ ] =~ /9/ and ++$o; } $#$ar = $#$ar - $o; $I == 1 and print "2: ", "@$ar"; ], build_new_array=>q[ my $ar = $as[3]; my @b; for( @$ar ) { push @b, $_ unless /9/; } $I == 1 and print "3: ", "@b"; ], edit_in_place=>q[ my $ar = $as[4]; my $o = 0; for( @$ar ) { $ar->[$o++] = $_ unless /9/; } $#$ar = $o - 1; $I == 1 and print "4: ", "@$ar"; ], };
I get yet another set of numbers:
Which just goes to prove a) be careful what you benchmark; b) O(n2) in C can often be considerably faster than O(n) in Perl; if the former avoids the multiple opcodes of the latter.
WHere the copy-offset (or your in-place) really come into their own is when the array being filtered is close to the limits of your memory to start with.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^4: foreach array - delete current row ? (flaws)
by roboticus (Chancellor) on Jun 03, 2013 at 18:05 UTC | |
|
Re^4: foreach array - delete current row ? (flaws)
by Anonymous Monk on Apr 27, 2015 at 01:55 UTC | |
by BrowserUk (Patriarch) on Apr 27, 2015 at 08:24 UTC |