Let us ignore for a moment Damian Conway\'s best practice of no more than three positional parameters for any given subroutine.
Is there any difference between the t
At least on my systems, it seems to depend upon the version of Perl and architecture:
#!/usr/bin/perl -w
use strict;
use warnings;
use autodie;
use Benchmark qw( cmpthese );
print "Using Perl $] under $^O\n\n";
cmpthese(
-1,
{
shifted => 'call( \&shifted )',
list_copy => 'call( \&list_copy )',
}
);
sub call {
$_[0]->(1..6); # Call our sub with six dummy args.
}
sub shifted {
my $foo = shift;
my $bar = shift;
my $baz = shift;
my $qux = shift;
my $quux = shift;
my $corge = shift;
return;
}
sub list_copy {
my ($foo, $bar, $baz, $qux, $quux, $corge) = @_;
return;
}
Results:
Using Perl 5.008008 under cygwin
Rate shifted list_copy
shifted 492062/s -- -10%
list_copy 547589/s 11% --
Using Perl 5.010000 under MSWin32
Rate list_copy shifted
list_copy 416767/s -- -5%
shifted 436906/s 5% --
Using Perl 5.008008 under MSWin32
Rate shifted list_copy
shifted 456435/s -- -19%
list_copy 563106/s 23% --
Using Perl 5.008008 under linux
Rate shifted list_copy
shifted 330830/s -- -17%
list_copy 398222/s 20% --
So it looks like list_copy is usually 20% faster than shifting, except under Perl 5.10, where shifting is actually slightly faster!
Note that these were quickly derived results. Actual speed differences will be bigger than what's listed here, since Benchmark also counts the time taken to call and return the subroutines, which will have a moderating effect on the results. I haven't done any investigation to see if Perl is doing any special sort of optimisation. Your mileage may vary.
Paul
Usually I use the first version. This is because I usually need to have error checking together with the shifts, which is easier to write. Say,
sub do_something_fantastical {
my $foo = shift || die("must have foo");
my $bar = shift || 0; # $bar is optional
# ...
}
There's a functional difference. The shift modifies @_
, and the assignment from @_
does not. If you don't need to use @_
afterward, that difference probably doesn't matter to you. I try to always use the list assignment, but I sometimes use shift
.
However, if I start off with shift
, like so:
my( $param ) = shift;
I often create this bug:
my( $param, $other_param ) = shift;
That's because I don't use shift
that often, so I forget to get over to the right hand side of the assignment to change that to @_
. That's the point of the best practice in not using shift
. I could make separate lines for each shift
as you did in your example, but that's just tedious.