in reply to Silly question about function args

According to Benchmark the first form is very slightly faster, but probably not enough to make much of a difference.
use Benchmark qw/cmpthese/; sub s1 {my ($arg1, $arg2, $arg3) = @_;}; sub s2 { my $arg1 = shift; my $arg2 = shift; my $arg3 = shift; } cmpthese(200000, { shift => ' { s2(1,2,3) }', list => ' {s1(1,2,3)}', }) Benchmark: timing 200000 iterations of list, shift... list: 3 wallclock secs ( 2.14 usr + 0.01 sys = 2.15 CPU) @ 93 +023.26/s (n=200000) shift: 2 wallclock secs ( 2.25 usr + 0.02 sys = 2.27 CPU) @ 88 +105.73/s (n=200000) Rate shift list shift 88106/s -- -5% list 93023/s 6% --

Replies are listed 'Best First'.
Re: Re: Silly question about function args
by integral (Hermit) on Feb 09, 2003 at 09:46 UTC
    The fastest way to pass arguments is not to copy them at all, and to access them inplace in @_. (This of course doesn't make readable code). The test case below illustrates this poorly for a simplified function.

    Update: BrowserUk's answer demonstrates this better.

    use Benchmark qw/cmpthese/; sub s1 {my ($arg1, $arg2, $arg3) = @_; $arg+$arg2+$arg3 }; sub s2 { my $arg1 = shift; my $arg2 = shift; my $arg3 = shift; $arg1+$ +arg2+$arg3} sub s3 {$_[0] + $_[1] + $_[2] } cmpthese(200000, { shift => ' { s2(1,2,3) }', list => ' {s1(1,2,3)}', none => ' {s3(1,2,3)}', }) Benchmark: timing 200000 iterations of list, none, shift... list: 4 wallclock secs ( 1.39 usr + 0.00 sys = 1.39 CPU) @ 14 +3884.89/s (n=200000) none: 1 wallclock secs ( 0.70 usr + 0.01 sys = 0.71 CPU) @ 28 +1690.14/s (n=200000) shift: 2 wallclock secs ( 1.46 usr + 0.03 sys = 1.49 CPU) @ 13 +4228.19/s (n=200000) Rate shift list none shift 134228/s -- -7% -52% list 143885/s 7% -- -49% none 281690/s 110% 96% --

    --
    integral, resident of freenode's #perl
    
      The fastest way to pass arguments is not to copy them at all

      Exactly. Inline the function entirely. Thats much faster.

      and to access them inplace in @_

      Persoanlly I would caution against this. An innocuous change of

      my $foo=shift; $foo=~s/A.//g; # to $_[0]=~s/A.//g;
      Would alter the original variable. Better to do away with the subroutine entirely. Then at least this effect is obvious and as I said you avoid the subroutine jump overhead.

      --- demerphq
      my friends call me, usually because I'm late....