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

Re: Optimizing the bejeezus out of a sub

by dws (Chancellor)
on Jun 24, 2003 at 07:15 UTC ( [id://268409]=note: print w/replies, xml ) Need Help??


in reply to Optimizing the bejeezus out of a sub

Any ideas where to look for that last little bit of performance?

The first thing that jumped out when I looked over your code is the loop. It looks like something transcribed from C. Instead of

for(;@_;shift) { ... ... @_[0] ...
try doing something like
foreach ( @_ ) { ... ... $_ ...
This plays to Perl's strengths (and saves you a few array subscripts). Or, if you want to be explicit,
foreach my $section ( @_ ) { ...

Replies are listed 'Best First'.
Re: Re: Optimizing the bejeezus out of a sub
by diotalevi (Canon) on Jun 24, 2003 at 11:52 UTC

    I wrote about the C-style for() in Re: Re: Believably slow... It is slower than the foreach() style for. Not significantly but slightly. I could only remove a few operations from your code, I noted each spot with an ALTER comment. I think your time is consumed by those print() statement - IO is always expensive.

    ## Print the given template sections to the supplied filehandle sub printto { my $self = shift; my $fh = shift; my $ret = 0; my($val,$sec,$v); # ALTER - foreach over C-style for foreach my $sec_k (@_) { $sec = $self->[_sec]{$sec_k}; # ALTER - drop unnecessary defined() unless ( $sec ) { # ALTER - remove indirect object syntax $fh->print( $self->_nosuchsec($sec_k) ); next; } $ret++; foreach $v (@$sec) { if ($v->[_type] == type_text) { # ALTER - remove indirect object syntax $fh->print( $v->[_contents] ); } else { $val = $self->[_assign]{$v->[_contents]}; $fh->print( defined $val ? $val : $self->_nosuchvar($val,"\$".$val) ); } } } return $ret; }

      Thanks for the suggestions! Here's what I found...

      I already changed the loops to use foreach; that seemed to be a little faster, and a lot more readable, so all benchmarks already have that in it. Here's what the numbers looked like before the other two changes:

      Total Elapsed Time = 43.18577 Seconds
        User+System Time = 42.69577 Seconds
      Exclusive Times
      %Time ExclSec CumulS #Calls sec/call Csec/c  Name
       48.8   20.83 20.710 130000   0.0002 0.0002  FTS::printto
      

      Changing if(!defined($sec)) to unless($sec) seemed to slow printto down just a hair. This could just be measurement error; for some reason apparently other parts of the code sped up with this change, which again points to measurement error...

      Total Elapsed Time = 41.62356 Seconds
        User+System Time = 41.09356 Seconds
      Exclusive Times
      %Time ExclSec CumulS #Calls sec/call Csec/c  Name
       51.3   21.09 20.905 130000   0.0002 0.0002  FTS::printto
      

      Changing print $fh to $fh->print seemed to slow things down significantly. The IO::Handle::print changes who the print calls get charged to, so the ExclSec for printto goes down, but it's made up for by all the calls to IO::Handle::print, and the CumulS and overall time go way up...

      Total Elapsed Time = 51.91479 Seconds
        User+System Time = 51.32479 Seconds
      Exclusive Times
      %Time ExclSec CumulS #Calls sec/call Csec/c  Name
       41.5   21.31 18.510 281000   0.0000 0.0000  IO::Handle::print
       38.9   19.97 35.589 130000   0.0002 0.0003  FTS::printto
      

        I have a hard time believing that you are really attempting to slice half a second off of your runtime. Results like this are easily attributed to system noise and frankly, I don't think that its worth spending this time on such miniscule results.

Re: Re: Optimizing the bejeezus out of a sub
by sgifford (Prior) on Jun 24, 2003 at 07:38 UTC
    My goal was to speed things up by avoiding copying each value from @_ to $section. While foreach is certainly more aesthetic, some benchmarking shows it to be about the same speed as my loop.

    I'm a little surprised by this, actually; I expected using @_ directly to always be faster, since it would avoid copying values.

      foreach my $section ( @_ ) { ... } doesn't copy value from @_ to $section. In the loop the variable $section is merely an alias to a currently selected element in @_ array. You can even modify @_ array by assigning a new value to $section. Example:

      # adds 1 to all elements of array foreach my $elem (@arr) { $elem ++; }

      --
      Ilya Martynov, ilya@iponweb.net
      CTO IPonWEB (UK) Ltd
      Quality Perl Programming and Unix Support UK managed @ offshore prices - http://www.iponweb.net
      Personal website - http://martynov.org

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (1)
As of 2024-04-25 05:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found