I think your benchmark is still flawed because you're applying a destructive operation multiple times without re-initializing the test data in between.
You're correct! (Strange how we all missed that.)
To correct for my error, I've re-visited the benchmark and corrected for that deficiency. (And hopefully not missed or introduced any other errors!)
I've tried to make this produce output as close to benchmarks as I can without getting anal about it:
#! perl -slw use strict; use Time::HiRes qw[ time ]; use Data::Dump qw[ pp ]; $Data::Dump::WIDTH = 1000; our $N //= 1e3; our $I //= 10; my @tests = qw[ forSplice grep offsetCopy buildNew editInplace ]; my %times = map{ $_ => 0 } @tests; my( $start, $end ); my @a; for( 1 .. $I ) { @a = 1 .. $N; $start = time; { $a[$_] =~ /9/ and splice @a, $_, 1 for reverse 0 .. $#a; # pp \@a; } $times{ forSplice } += time() - $start; @a = 1 .. $N; $start = time; { @a = grep !/9/, @a; # pp \@a; } $times{ grep } += time() - $start; @a = 1 .. $N; $start = time; { my $o = 0; for( 0 .. $#a ) { $a[ $_ - $o ] = $a[ $_ ]; $a[ $_ ] =~ /9/ and ++$o; } $#a = $#a - $o; # pp \@a; } $times{ offsetCopy } += time() - $start; @a = 1 .. $N; $start = time; { my @b; for( @a ) { push @b, $_ unless /9/; } # pp \@b; } $times{ buildNew } += time() - $start; @a = 1 .. $N; $start = time; { my $o = 0; for( @a ) { $a[ $o++ ] = $_ unless /9/; } $#a = $o - 1; # pp \@a; } $times{ editInplace } += time() - $start; }; $times{ $_ } /= $I for @tests; #pp \%times; @tests = sort{ $times{ $a } < $times{ $b } } @tests; print join '', map sprintf( " %12s", $_ ), '', 'rate', @tests; for my $a ( @tests ) { printf "%12s %10g/s", $a, 1/$times{ $a }; for my $b ( @tests ) { printf " %11.f%%", $times{ $b } / $times{ $a } * 100; } print ''; } __END__ C:\test>1036622 -N=1e2 rate grep forSplice buildNew of +fsetCopy editInplace grep 7687.51/s 100% 61% 76% + 75% 58% forSplice 12539/s 163% 100% 124% + 123% 95% buildNew 10082.5/s 131% 80% 100% + 99% 76% offsetCopy 10182.8/s 132% 81% 101% + 100% 77% editInplace 13206.2/s 172% 105% 131% + 130% 100% C:\test>1036622 -N=1e3 rate grep forSplice buildNew of +fsetCopy editInplace grep 760.637/s 100% 63% 78% + 75% 59% forSplice 1201.22/s 158% 100% 123% + 119% 93% buildNew 973.269/s 128% 81% 100% + 97% 75% offsetCopy 1007.76/s 132% 84% 104% + 100% 78% editInplace 1293.34/s 170% 108% 133% + 128% 100% C:\test>1036622 -N=1e4 rate grep forSplice offsetCopy +buildNew editInplace grep 72.5919/s 100% 97% 79% + 73% 54% forSplice 74.7857/s 103% 100% 81% + 75% 56% offsetCopy 92.2046/s 127% 123% 100% + 92% 69% buildNew 99.9543/s 138% 134% 108% + 100% 75% editInplace 133.395/s 184% 178% 145% + 133% 100% C:\test>1036622 -N=1e5 rate forSplice grep offsetCopy +buildNew editInplace forSplice 1.13766/s 100% 17% 13% + 13% 10% grep 6.60517/s 581% 100% 77% + 73% 59% offsetCopy 8.63102/s 759% 131% 100% + 95% 78% buildNew 9.05601/s 796% 137% 105% + 100% 82% editInplace 11.1044/s 976% 168% 129% + 123% 100% C:\test>1036622 -N=1e6 -I=1 rate forSplice grep offsetCopy +buildNew editInplace forSplice 0.0106761/s 100% 1% 1% + 1% 1% grep 0.798803/s 7482% 100% 86% + 73% 63% offsetCopy 0.929497/s 8706% 116% 100% + 85% 73% buildNew 1.09032/s 10213% 136% 117% + 100% 86% editInplace 1.26927/s 11889% 159% 137% + 116% 100%
The upshot is that forSplice is a little faster than grep for small arrays; but editInPlace is hands down winner for arrays of any size; and one or two orders of magnitude for large arrays.
In reply to Re^5: foreach array - delete current row ? (flaws)
by BrowserUk
in thread foreach array - delete current row ?
by JockoHelios
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |