Which is more efficient call --> goto &fun($val) or fun($val) in perl ?
Which is more efficient statement --> goto &fun($val) or fun($val) in perl ? When to use which statement for better perf开发者_开发知识库ormance ? Please let me know the answer !
I think this is the wrong question to ask.
The form fun($val)
is the standard way to call another subroutine in perl.
The form goto &func
is normally used to transfer control to another sub while removing the current stack frame. In addition, @_
is passed unaltered to the called routine.
The removal of the stack frame means that caller()
will not see it, so that the &func
will think that t was called by the caller of the routine which performed the goto
. It also means that performing a backtrace in the debugger will not reveal the routine performing the goto
.
If you want to preserve the calling stack frame but pass control to a function with the current setting of @_
, then use return &func
.
The form goto &func($val)
is parsed as:
my $label = &func($val);
goto $label;
This will likely give a Can't find label ...
error.
Examples:
sub func {
my $x = shift;
print "x = $x\n";
my ($package, $file, $line) = caller();
print "caller file: $file, line: $line\n";
}
sub foo {
goto &func("from goto bar");
}
sub baz {
return &func;
}
sub quux {
goto &func;
}
baz("from baz");
quux("from quux");
foo("from foo");
Surprise of my life. The no-goto version seems to be faster. So little reason to use anything else than normal function calls, apart from deep recursion.
Rate with_goto no_goto
with_goto 56818/s -- -21%
no_goto 71942/s 27% --
Tested with this:
use Benchmark ':all';
sub with_goto { $_[0]-- and goto &with_goto }
sub no_goto { $_[0]-- and & no_goto }
cmpthese( 100000, {
with_goto => '$_=98; with_goto($_)',
no_goto => '$_=98; no_goto($_)',
});
(still baffled)
Always use fun($val)
. It's more readable and any performance difference will be small enough that, if it matters to you, then you shouldn't be using Perl in the first place. Not to mention that the goto
version probably doesn't do what you intend anyhow - they are not synonymous.
Unless you've already profiled your code to determine that subroutine dispatching is taking up a significant portion of your CPU cycles (highly unlikely that it would be!) and you've benchmarked code to compare the two ways of doing it to ensure that, in your particular case, there is enough of a difference for it to matter (even less likely!), this is a very, very premature optimization. If you're having performance problems, look at your algorithms instead of worrying about such a tiny, tiny microoptimization.
精彩评论