哪个是更有效的通话 - > perl中的goto& fun($ val)或fun($ val)?

时间:2011-09-13 13:24:34

标签: perl goto

哪个是更有效的陈述 - > perl中的goto& fun($ val)或fun($ val)? 何时使用哪个声明以获得更好的性能? 请让我知道答案!

3 个答案:

答案 0 :(得分:11)

我认为这是一个错误的问题。

表单fun($val)是在perl中调用另一个子例程的标准方法。

表单goto &func通常用于在删除当前堆栈帧的同时将控制权转移到另一个子目录。此外,@_将不加改变地传递给被调用的例程。

删除堆栈帧意味着caller()将无法看到它,因此&func会认为执行goto的例程的调用者调用了t。这也意味着在调试器中执行回溯不会显示执行goto的例程。

如果要保留调用堆栈帧但将控制权传递给当前设置为@_的函数,则使用return &func

表单goto &func($val)被解析为:

my $label = &func($val);
goto $label;

这可能会导致Can't find label ...错误。

示例:

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");

答案 1 :(得分:3)

我生命的惊喜。 no-goto版似乎更快。除了深度递归之外,没有什么理由可以使用除正常函数调用以外的任何其他函数。

             Rate with_goto   no_goto
with_goto 56818/s        --      -21%
no_goto   71942/s       27%        --

经过测试:

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($_)',
});

(仍然感到困惑)

答案 2 :(得分:2)

始终使用fun($val)。它更具可读性,任何性能差异都足够小,如果对你很重要,那么你不应该首先使用Perl。更不用说goto版本可能无论如何都不会做你想要的 - 它们不是同义词。

除非你已经分析了你的代码,以确定子程序调度占用你的CPU周期的很大一部分(这不太可能!)你已经对基准代码进行了比较这两种方式可以确保在您的特定情况下,它有足够的差异(甚至不太可能!),这是一个非常非常不成熟的优化。如果您遇到性能问题,请查看您的算法,而不是担心这种微小的微小优化。