Подпрограммы-константы, то есть подпрограммы с пустым прототипом и постоянным возвращаемым значением, являются встроенными. Вот как прагма constant определяет константы:
sub five() { 5 }
будет встроен, если его увидят до первого использования.
В противном случае Perl позволяет динамически переопределять подпрограммы во время выполнения, поэтому вставка не подходит.
Для подпрограмм, которые всегда возвращают одно и то же значение при одинаковых входных данных, вы можете использовать memoization .
Глава 13 программирования Perl предоставляет некоторую информацию о шагах по оптимизации, предпринятых perl
.
Это называется постоянным складыванием. Постоянное свертывание не ограничивается простыми случаями, такими как превращение 2 ** 10 в 1024 во время компиляции. Он также разрешает вызовы функций - как встроенные, так и объявленные пользователем подпрограммы, которые соответствуют критериям из раздела «Встроенные функции констант» в главе 6 «Подпрограммы». Напоминая о печально известном знании компиляторами FORTRAN собственных встроенных функций, Perl также знает, какие из своих встроенных функций следует вызывать во время компиляции. Вот почему, если вы попытаетесь получить лог 0.0 или sqrt отрицательной константы, вы получите ошибку компиляции, а не ошибку времени выполнения, и интерпретатор никогда не будет запущен вообще.
См. Также perldoc perlguts .
Вы можете увидеть эффект постоянного сворачивания самостоятельно:
#!/usr/bin/perl
use strict; use warnings;
sub log_ok () { 1 }
if ( log_ok ) {
warn "log ok\n";
}
perl -MO=Deparse t.pl
Выход:
sub log_ok () { 1 }
use warnings;
use strict 'refs';
do {
warn "log ok\n"
};
t.pl syntax OK
Здесь постоянное сворачивание привело к замене блока if
на блок do
, поскольку компилятор знал, что log_ok
всегда будет возвращать истинное значение. С другой стороны, с:
#!/usr/bin/perl
use strict; use warnings;
sub log_ok () { 0.5 > rand }
if ( log_ok ) {
warn "log ok\n";
}
Разбавить вывод:
sub log_ok () {
use warnings;
use strict 'refs';
0.5 > rand;
}
use warnings;
use strict 'refs';
if (log_ok) {
warn "log ok\n";
}
t.pl syntax OK
Компилятор C
мог бы заменить if (log_ok)
на if ( 0.5 > rand )
. perl
не делает этого.