in reply to Inline Subs Revisited
I think if you are going to do this, then you should avoid trying to emulate what a subroutine does (and can do) quite so slavishly.
Whilst you will gain some performance using your inlined block over a sub call--around 61% (b .v. c) on the evidence of the simple sub below; it will lessen the more you do in the sub.
You gain more by simply avoiding the copying of the parameters into named vars within the sub. (c .v. a) 71%.
But if you're going to inline, why not eliminate the block and the copying by substituting the parameters directly into the body of the sub and placing that directly inline? This gives (d .v. c) 750% improvement (for this trivial sub):
sub s1{ $_[0] + $_[1] } sub s2{ my( $x, $y ) = @_; $x + $y; } cmpthese -1, { a=>q[ my $z = s1( 1, 2 ); ], b=>q[ my $z; { my( $x, $y ) = (1,2); $z = $x + $y } ], c=>q[ my $z = s2( 1, 2); ], d=>q[ my $z = 1 + 2; ], };; Rate c b a d c 1452758/s -- -38% -42% -88% b 2344698/s 61% -- -6% -81% a 2483364/s 71% 6% -- -80% d 12297390/s 746% 424% 395% --
I realise that this limits the forms of the subs you can inline to fairly simple ones, but that's probably for the best anyway. 1) because it makes the parsing of the bodies simpler. 2) there are rapidly diminishing returns from inlining more complex subs.
I did some experiments a few years ago to try and find out where the point of diminishing returns actually lay, but it is quite hard to come up with convincing generic guidelines. From memory, even a couple of nested blocks within the subroutine that declared local vars and you were in to the realms of uncertainty over whether any real gain was to be had or not. I'll try to resurrect an example from the backup CD of my old machine.
|
|---|