常量子例程,即具有空原型和常量返回值的子例程,是内联的。就是这样constantpragma 定义常量:
sub five() { 5 }
如果在第一次使用之前看到它,则会被内联。
否则,Perl 允许在运行时动态重新定义子例程,因此内联不适合。
对于给定相同输入总是返回相同值的子例程,您可以使用记忆化.
Perl 编程第 13 章提供了有关所采取的优化步骤的一些信息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
Output:
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
A C
编译器可能已经替换了if (log_ok)
with if ( 0.5 > rand )
. perl
不这样做。