Laz*_*zer 9 perl inline subroutine
我正在阅读代码完成2,其中一个要点是关于创建子程序,即使对于看起来太简单而无法拥有自己的子程序的操作,以及它如何有用.
我知道我可以使用关键字在C和C++中内联函数inline.但我从未想过在Perl中内联子程序的方法.
有没有办法告诉Perl解释器内联子程序调用(或为什么不)?
Sin*_*nür 24
常量子例程,即具有空原型和常量返回值的子例程,是内联的.这就是常量 pragma定义常量的方式:
sub five() { 5 }
Run Code Online (Sandbox Code Playgroud)
如果在第一次使用之前看到它将被内联.
否则,Perl允许在运行时动态重新定义子例程,因此内联不适合.
对于在给定相同输入的情况下始终返回相同值的子例程,可以使用memoization.
Programming Perl的第13章提供了有关所采取的优化步骤的一些信息perl.
这称为恒定折叠.常量折叠不仅限于简单的情况,例如在编译时将2**10转换为1024.它还解析函数调用 - 内置函数和用户声明的子例程,它们满足第6章子例程中"内联常量函数"一节中的条件.让人联想到FORTRAN编译器对其内在函数的臭名昭着的知识,Perl也知道在编译期间调用哪个内置函数.这就是为什么如果你尝试获取0.0的日志或负常量的sqrt,你将产生编译错误,而不是运行时错误,并且解释器根本不会运行.
你可以看到自己不断折叠的效果:
#!/usr/bin/perl
use strict; use warnings;
sub log_ok () { 1 }
if ( log_ok ) {
warn "log ok\n";
}
Run Code Online (Sandbox Code Playgroud)
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";
}
Run Code Online (Sandbox Code Playgroud)
稀疏输出:
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不这样做.
Perl只允许内联常量函数.来自perldoc perlsub:
具有()原型的函数是内联的潜在候选者.如果优化和常量折叠后的结果是常量或没有其他引用的词法范围的标量,那么它将用于代替没有&的函数调用.
| 归档时间: |
|
| 查看次数: |
6817 次 |
| 最近记录: |