如何内联 Perl 子例程?
我正在阅读Code Complete 2,其中提到的一点是关于创建子例程,即使是对于看似的操作太简单了,没有自己的子例程,这会有什么帮助。
我知道我可以使用 inline
关键字C 和 C++ 中的内联函数。但我从未遇到过在 Perl 中内联子例程的方法。
有没有办法告诉 Perl 解释器内联子例程调用(或者为什么不)?
I am reading Code Complete 2, and one of the points mentioned is about creating subroutines even for operations that seem too simple to have their own subroutines, and how that can be helpful.
I know I can inline functions in C and C++ using the inline
keyword. But I never came across a way to inline subroutines in Perl.
Is there a way to tell the Perl interpreter to inline the subroutine calls (or why not)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
常量子例程,即具有空原型和常量返回值的子例程,是内联的。这就是 constant 编译指示定义常量的方式:
如果在第一次使用之前看到它,则它将被内联。
否则,Perl 允许在运行时动态重新定义子例程,因此内联不适合。
对于在给定相同输入的情况下始终返回相同值的子例程,您可以使用记忆化。
《Perl 编程》第 13 章 提供了有关所采取的优化步骤的一些信息由 Perl 编写。
另请参阅 perldoc perlguts。
您可以自己看到常量折叠的效果:
输出:
这里,常量折叠导致用
do
块替换if
块,因为编译器知道>log_ok
总是返回一个真值。另一方面,使用:Deparse 输出:
C
编译器可能已将if (log_ok)
替换为if ( 0.5 > rand )
。perl
不这样做。Constant subroutines, i.e. subroutines with an empty prototype and constant return value, are inline. That is how the constant pragma defines constants:
would be inlined if it is seen before its first use.
Otherwise, Perl allows subroutines to be dynamically redefined at run time, so inlining is not suitable.
For subroutines that always return the same value given the same inputs, you can use memoization.
Chapter 13 of Programming Perl provides some information on the optimization steps taken by
perl
.See also perldoc perlguts.
You can see the effect of constant-folding yourself:
Output:
Here, constant folding led to the replacement of the
if
block with ado
block because the compiler knew thatlog_ok
would always return a true value. On the other hand, with:Deparse output:
A
C
compiler might have replaced theif (log_ok)
withif ( 0.5 > rand )
.perl
does not do that.Perl 只允许内联常量函数。来自 perldoc perlsub:
Perl only allows to inline constant functions. From perldoc perlsub:
我还没有尝试过这些,但如果你有时间,你可以尝试
Macro< /code>
宏
Filter::Macro
它们都是源过滤器,所以你'您必须检查您的绩效投资回报。
最后一篇实际上对 cpan ratings 进行了评论。 (忽略 Dan Dascalescu 试图规范 Perl 模块“空域”。)
-- 实际上,最后一个
Filter::Macro
使用Filter::Simple::Compile
(依次使用Module::Compile
) 来编译例程,因此这可能会在其他源过滤器方法之上执行。但是标准警告对源过滤器适用。I haven't tried any of these, but if you have the time, you could try
Macro
macro
Filter::Macro
They're all source filters so you'll have to check your return on investment in performance.
The last actually has a review on cpanratings. (Ignore Dan Dascalescu's attempt to regulate the Perl module "airspace".)
-- Actually, the last one
Filter::Macro
usesFilter::Simple::Compile
(which in turn usesModule::Compile
) to compile the routines, so this might perform above the other source filter methods. But the standard caveats on source filters apply.编写 Perl 时,速度可能不应该成为考虑因素。继续让事情发挥作用。如果稍后的分析显示您由于频繁调用一个简单函数而花费了大量时间,那么您可以自己内联该函数。
Speed should probably not be a consideration when writing Perl. Go ahead and make things functions. If profiling later shows that you are spending a lot of time in a simple function due to calling it a lot, then inline that function yourself.