Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Re: Optimizing existing Perl code (in practise)

by gmpassos (Priest)
on Aug 19, 2002 at 11:47 UTC ( [id://191141]=note: print w/replies, xml ) Need Help??


in reply to Optimizing existing Perl code (in practise)

Well, if you really want to make some code faster make a XS, in other words make it in C. But this is only good to do with filters, crypters, etc...

To win speed, you can make tests of your code, specially inside loops, peaces that will be runned a lot of times, to find the best way to write it! Here are some tips:

Variables:
Don't use:
$var = $var . "add" ;
The best way is:
$var .= "add" ;
The first way (wrong) will rewrite all the variable in the memory, the second will only add the new data. Use the same idea for: += , -= , *= , /=

For subs use the content of the @_, specially for big data sent to the function. 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".
Don't use for big data:
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, you need to past to a $scalar.

If you have a loop (while,for,foreach) that will be runned a lot of times, try to not use the my inside it:
Normal way: for(0..10) { my $var = $_ ; }
Faster:
my $var ;
for(0..10) { $var = $_ ; }
* Of course this will only improve speed if you try to make the my outside for all the variables, in other words for bigger codes inside the loop.

Don't use local(), my() is faster! The command local() in the begin of perl was used like my, but now it's only good if you want to make local *HANDLES, not variables.

Try to use the variables in this order: $scalar, @array, %hash. Some thimes we use %h or @a and they aren't needed, but they are more slower than $s and use more memory, specially %h!

About regular expressions (RE), use it only when it's needed! Dont make this: if($var =~ /x/) if you can do if($var eq 'x'). But some times RE can be faster than bigger codes, the best way to chose is test the 2 codes.

But always think that any tip here will improve some microseconds for you. Only spend time improving speed in the peaces of your code that really need! Always try to use the resources of core, don't remake things that can be made by Perl it self.

"The creativity is the expression of the liberty".

Replies are listed 'Best First'.
Re: Re: Optimizing existing Perl code (in practise)
by RMGir (Prior) on Aug 20, 2002 at 12:18 UTC
    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
      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

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://191141]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (7)
As of 2024-04-16 11:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found