Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Re: Optimizing the bejeezus out of a sub

by BrowserUk (Patriarch)
on Jun 24, 2003 at 13:10 UTC ( [id://268483]=note: print w/replies, xml ) Need Help??


in reply to Optimizing the bejeezus out of a sub

The only thing left inside the routine that might be trimable is the inner foreach loop. If the list of aliases generated by @$sec is of any size, then you maybe paying a time penalty for building that list, and might realise some saving by using indexes to iterate over the array

for (0..$#{$sec}) { $sec->[$_][_type]... }

Also, if _type,  _sec & _contents aren't already defined as constants (which are usually UPPERCASE by convention) then making them constants may yield another minor improvement.

However, given that each call to the routine is only taking an average of 0.000165 seconds, there isn't exactly a lot of fat to be trimed within the routine. The fact that you are spending 50% of your programs time, a little over 20 seconds in there comes down to the fact that you are calling it 130,000 times.

There are a few possibilities that might improve things.

  • Currently, even with the improvement of building your output string up within the routing and printing it once at the end of each call, you are still calling the built-in print 130,000 times. You might save a little by accumulating the output from all 130,000 calls in a string using something like

     $self->[_output] .= ... and then calling print once at the end of the (external) loop that is calling this 130,000 times.

  • The other, and more likely candidate for cutting down your overall execution time is to reduce the number of times you call the routine. Whether that is possible depends on the nature of that external loop.

If there is no possibility of reducing the 130,000 calls to the routine, then you might save some by not calling the routine! That is to say, if you inlined the sub at the point(s) of call, you would save the cost of building the stackframe and calling it.

Whether this is

  • possible, given the architecture of the application.
  • desirable, given the probable redundancy that inlining might create and all the caveats that go with it

Are both questions you must decide given your requirements. How much benefit is realisable will depend on the nature of the code that calls this routine.

As an attempt to give some indication, the following (unrepresentative and possibly misrepresentative) benchmark shows that under some circumstances, inlining and/or deferring the printing, can yield some possibly significant benefits.

#! perl -slw use strict; use Benchmark qw[cmpthese]; sub printto { print {$_[0]} $_[1]; return; } sub defer { ${$_[0]} .= $_[1].$/; return; } open our $fh, '>', 'junk.out' or die $!; cmpthese( -60, { direct=> q[ print $fh 'Direct'; for(0..130_000) { printto $fh, $_; } ], inlined=> q[ print $fh 'Inlined'; for(0..130_000) { print $fh $_; } ], deferred=> q[ print $fh 'Deferred'; my $output = ''; for(0..130_000) { defer \$output, $_ } print $fh $output; ], inline_deferred=> q[ print $fh 'Inline-deffered'; my $output=''; for(0..130_000) { $output .= $_ . $/; } print $fh $output; ], }); close $fh; __END__ D:\Perl\test>test s/iter direct inlined deferred inlin +e_deferred direct 7.57 -- -48% -57% + -85% inlined 3.93 93% -- -17% + -71% deferred 3.26 132% 20% -- + -65% inline_deferred 1.13 568% 247% 188% + --

Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller


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

    The listification of @_ was optimized away by perl so foreach accessed the array directly. Using offsets to counteract the not-actually-happening maloptimization is a maloptimization in and of itself.

      I said might!

      Can you substantiate that the listification is always optimised away?


      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller


        No. I verified that the case of for(LIST(@_)){ ... } is optimized away into for(@_){ ... } because that is what is in the original code. I also (since you just asked) tried for(@A,@B), for(@A,@B,1) and in all cases the list op was removed. Maybe the list op shows back up when there is something non-simple to read from - functions and builtins.

Log In?
Username:
Password:

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

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

    No recent polls found