Что является более эффективным call -> goto & fun ($ val) или fun ($ val) в perl? - PullRequest
2 голосов
/ 13 сентября 2011

Какое более эффективное утверждение -> goto & fun ($ val) или fun ($ val) в perl?Когда использовать какое утверждение для лучшей производительности?Пожалуйста, дайте мне знать ответ!

Ответы [ 3 ]

11 голосов
/ 13 сентября 2011

Я думаю, что это неправильный вопрос.

Форма fun($val) - это стандартный способ вызова другой подпрограммы в perl.

Форма goto &func обычно используется для передачи управления другому подчиненному при удалении текущего кадра стека. Кроме того, @_ передается без изменений в вызываемую подпрограмму.

Удаление кадра стека означает, что caller() не увидит его, поэтому &func будет думать, что t вызвал вызывающий подпрограммы, которая выполнила goto. Это также означает, что выполнение обратной трассировки в отладчике не будет показывать процедуру, выполняющую 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");
3 голосов
/ 13 сентября 2011

Сюрприз моей жизни. Версия 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 голосов
/ 13 сентября 2011

Всегда используйте fun($val). Он более читабелен, и любая разница в производительности будет достаточно мала, поэтому, если это имеет значение для вас, вам не следует использовать Perl. Не говоря уже о том, что версия goto, вероятно, в любом случае не выполняет то, что вы намереваетесь - они не синонимичны.

Если вы уже не профилировали свой код, чтобы определить, что подпрограмма диспетчеризации занимает значительную часть ваших циклов ЦП (весьма маловероятно, что это будет!) и вы тестировали код для сравнения два способа сделать это, чтобы гарантировать, что в вашем конкретном случае достаточно различий, чтобы оно имело значение (даже менее вероятно!), это очень, очень преждевременная оптимизация. Если у вас проблемы с производительностью, посмотрите на свои алгоритмы, а не беспокойтесь о такой крошечной микрооптимизации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...