in reply to Re: Optimizing the bejeezus out of a sub
in thread Optimizing the bejeezus out of a sub

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; }

Replies are listed 'Best First'.
Re: Re: Re: Optimizing the bejeezus out of a sub
by sgifford (Prior) on Jun 24, 2003 at 16:23 UTC

    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.

        You're probably right. I'm actually not interested in improving the runtime of this application specifically (most of the application's runtime is from timethis(10000,...)) but rather in making sure that my FTS module is as fast as possible.

        I'm using it to replace another module in several real-world applications, a heavily modified CGI::FastTemplate which has become a little hard to maintain. I was hoping to make FTS as fast as or faster than CGI::FastTemplate so I could replace it with zero reservations, but I don't seem to have succeeded, even with all of the tips offered here (CGI::FastTemplates runs like this on the same data:

        39 wallclock secs (35.76 usr +  1.93 sys = 37.69 CPU) @ 265.32/s (n=10000)
        
        ), but I think the extra maintainability is worth the slight slowdown .

        My other goal was to expand my knowledge of how to optimize Perl code, which I definitely did! :-)