in reply to Trying to slice off all array elements but the last one
All other things being equal, I'd use splice, the code is much more readable:
my @all_but_one = splice( @$arrayref, 0, -1 );
As an added bonus, it's also faster:
#! /usr/bin/perl -w use strict; use Benchmark qw/cmpthese/; my @x = qw/a b c/; sub with_splice { my $aref = shift; splice( @$aref, 0, -1 ); } sub with_range { my $aref = shift; @{$aref}[0 .. ($#{$aref} - 1)] } print 'range ', join( ' ' => with_range(\@x) ), "\n"; print 'splice ', join( ' ' => with_splice(\@x) ), "\n"; my @z = 0 .. 100_000; cmpthese( shift || 2_000_000, { short_splice => sub { with_splice(\@x) }, short_range => sub { with_range (\@x) }, } ); cmpthese( shift || 1_000, { long_splice => sub { with_splice(\@z) }, long_range => sub { with_range (\@z) }, } ); __RESULTS__ range a b splice a b Benchmark: timing 2000000 iterations of short_range, short_splice... short_range: 9 wallclock secs ( 7.83 usr + 0.00 sys = 7.83 CPU) @ 2 +55489.02/s (n=2000000) short_splice: 5 wallclock secs ( 5.06 usr + 0.01 sys = 5.07 CPU) @ +394453.00/s (n=2000000) Rate short_range short_splice short_range 255489/s -- -35% short_splice 394453/s 54% -- Benchmark: timing 1000 iterations of long_range, long_splice... long_range: 40 wallclock secs (39.73 usr + 0.02 sys = 39.74 CPU) @ 25 +.16/s (n=1000) long_splice: 0 wallclock secs ( 0.01 usr + 0.00 sys = 0.01 CPU) @ 1 +28000.00/s (n=1000) (warning: too few iterations for a reliable count) Rate long_range long_splice long_range 25.2/s -- -100% long_splice 128000/s 508600% --
As should be obvious (assuming I'm benchmarking the right thing :), the longer the array, the faster the splice.
update: actually, playing around with the code a bit (because arrays with around 100 000 elements are usually few and far between in production code), I reduced the size down to 500 elements, and the splice method shows no degradation, but the range operator does:
enchmark: timing 300000 iterations of short_range, short_splice... short_range: 2 wallclock secs ( 1.16 usr + 0.00 sys = 1.16 CPU) @ 2 +59459.46/s (n=300000) short_splice: 1 wallclock secs ( 0.75 usr + 0.00 sys = 0.75 CPU) @ +400000.00/s (n=300000) Rate short_range short_splice short_range 259459/s -- -35% short_splice 400000/s 54% -- Benchmark: timing 200000 iterations of long_range, long_splice... long_range: 36 wallclock secs (37.30 usr + 0.00 sys = 37.30 CPU) @ 53 +62.38/s (n=200000) long_splice: 0 wallclock secs ( 0.50 usr + 0.00 sys = 0.50 CPU) @ 4 +00000.00/s (n=200000) Rate long_range long_splice long_range 5362/s -- -99% long_splice 400000/s 7359% --
Well, that was fun.
|
|---|