http://www.perlmonks.org?node_id=191442


in reply to Re: Optimizing existing Perl code (in practise)
in thread Optimizing existing Perl code (in practise)

For subs use the content of the @_, specially for big data sent to the function:
Don't use:
sub { my ($var1,$var2) = @_ ; }
The best way is to use the @_[0] it self or the shift:
sub { my $var1 = shift ; my $var2 = shift ; }
* If you use @_[?] you can't modifie it! Use shift if you need to write to the var.

I was pretty sure that was wrong when I read it, so I whipped out Benchmark:

#!/usr/bin/perl -w use strict; use Benchmark qw(cmpthese); sub shifter { my $a=shift; my $b=shift; my $c=shift; my $d=shift; my $e=shift; my $f=shift; return $a*$b*$c*$d*$e*$f; } sub assigner { my ($a,$b,$c,$d,$e,$f)=@_; return $a*$b*$c*$d*$e*$f; } sub direct { return $_[0]*$_[1]*$_[2]*$_[3]*$_[4]*$_[5]; } cmpthese(-5, { 'shifter' => sub {shifter(1,2,3,4,5,6);}, 'assigner' => sub {assigner(1,2,3,4,5,6);}, 'direct' => sub {direct(1,2,3,4,5,6);}, } );
Results:
$ perl testSubs.pl Benchmark: running assigner, direct, shifter, each for at least 2 CPU +seconds... assigner: 0 wallclock secs ( 2.06 usr + 0.02 sys = 2.08 CPU) @ 384 +577.33/s (n=800690) direct: 3 wallclock secs ( 2.04 usr + 0.00 sys = 2.04 CPU) @ 629 +222.22/s (n=1285501) shifter: 2 wallclock secs ( 2.09 usr + 0.00 sys = 2.09 CPU) @ 294 +563.31/s (n=616521) Rate shifter assigner direct shifter 294563/s -- -23% -53% assigner 384577/s 31% -- -39% direct 629222/s 114% 64% --
That's with perl 5.6.1... Maybe 5.8.0 optimized shift? But you'd have to keep the old values around and have a "front" entry in the AV, and I don't remember seeing anything about that.
--
Mike

Replies are listed 'Best First'.
Re: Re: Re: Optimizing existing Perl code (in practise)
by gmpassos (Priest) on Aug 22, 2002 at 18:52 UTC
    Hy,

    The "shift" options is good to use when you send big data to the function! The process of the command is not fast, because it need to cut the value from the array, reorder the array, and create and save to a scalar variable! "shift" is good to use for big data because you don't leave in the memory the data 2 times! You just move to the scalar! If you want speed use first the @_[0], then if you need to change the data inside @_[0], you use my ($var) = @_ ;, and if you have big data you use the "shift".

    "The creativity is the expression of the liberty".

      The "shift" options is good to use when you send big data to the function! The process of the command is not fast, because it need to cut the value from the array, reorder the array, and create and save to a scalar variable! "shift" is good to use for big data because you don't leave in the memory the data 2 times!

      Good point!

      I'd try to avoid that by passing a reference to the large scalar to the sub instead, but if you're expecting possibly large scalar arguments by value (edit: because you need to modify them, maybe), you're right.
      --
      Mike

        "I'd try to avoid that by passing a reference to the large scalar to the sub instead"
        Better point! :)

        The reference is another good way! But is good only if you just want to past the data through the sub, because you can't read or edit it before parse the reference, and when you parse it you duplicate again the data in the memory.

        Of course that the best idea is always the simplest, why not put the variable with the "big data" in global (without 'my' or 'local'), to be read by all the program?
        K.I.S.S. -> Kip It Simple, Stupid! :-P

        "The creativity is the expression of the liberty".