in reply to Re: Array or Hash Reference to Subroutine
in thread How to use @EXPORT
You seem to be confusing passing by reference with passing a reference. Perl always passes by reference, whether what you are passing is a reference or not.
On the other hand, a sub that starts with my (...) = @_; or similar effectively causes Perl to pass by value, even when you pass a reference.
The difference is not between passing by reference and passing by value. The difference in the size of the list being passed. When passing a reference to an array to a sub, only one argument is placed on the stack. When passing an array's contents to a sub, as many arguments are placed on the stack as there are elements in the array.
Seeing as the latter is done using a simple memcpy, performance should not be an issue. And it isn't. Using the reference is actually 9% slower for a typical array (N=10)!
Rate list ref list_nc list 132332/s -- -52% -56% ref 273067/s 106% -- -9% list_nc 300755/s 127% 10% --
Even for very large arrays, the performance of just passing the array's elements is quite good. Passing all 10,000 elements of an array is only 14% slower than passing the reference alone!
Rate list list_nc ref list 148/s -- -69% -73% list_nc 469/s 218% -- -14% ref 545/s 269% 16% --
Performance gains is obviously not the reason passing references is done. (Although perceived performance gains could be.)
(I included a trivial load to get more reasonable numbers.)
Benchmark code:
use strict; use warnings; use Benchmark qw( cmpthese ); sub pass_ref { my ($a) = @_; my $x = ''; $x .= $_ for @$a; 1; } sub pass_list { my @a = @_; my $x = ''; $x .= $_ for @a; 1; } sub pass_list_no_copy { my $x = ''; $x .= $_ for @_; 1; } my %tests = ( ref => 'pass_ref(\@a);', list => 'pass_list(@a);', list_nc => 'pass_list_no_copy(@a);', ); $_ = 'use strict; use warnings; our @a; ' . $_ for values(%tests); our @a = ('-') x ( $ARGV[0] || 10 ); cmpthese(-1, \%tests);
|
|---|