代码之家  ›  专栏  ›  技术社区  ›  Aakash Goel

如何内联Perl子例程?

  •  9
  • Aakash Goel  · 技术社区  · 14 年前

    Code Complete 2 其中一个要点是创建子例程,即使是对于那些看起来太简单而无法拥有自己的子例程的操作,以及如何才能提供帮助。

    我知道我可以 inline functions in C and C++ inline 关键字。但我从未遇到过在Perl中内联子例程的方法。

    有没有办法告诉Perl解释器内联子例程调用(或者为什么没有)?

    4 回复  |  直到 14 年前
        1
  •  24
  •   Sinan Ünür    14 年前

    常量子例程,即具有空原型和常量返回值的子例程是内联的。这就是为什么 constant pragma定义常量:

    sub five() { 5 }
    

    否则,Perl允许在运行时动态重新定义子例程,因此内联不适合。

    对于在给定相同输入时始终返回相同值的子例程,可以使用 memoization

    Chapter 13 of Programming 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语言

        2
  •  5
  •   Eugene Yarmash    14 年前

    Perl只允许内联常量函数。从 perldoc perlsub :

    原型为()的函数是 优化后的结果 常数折叠不是常数 没有其他参考资料,那么 用于代替函数调用

        3
  •  3
  •   Community paulsm4    7 年前

    我没有试过这些,但如果你有时间,你可以试试

    1. Macro
    2. macro
    3. 甚至 Filter::Macro

    它们都是源代码过滤器,所以你必须检查你在性能上的投资回报。 最后一个实际上有一个关于 cpanratings

    -- 事实上 筛选器::宏 使用 Filter::Simple::Compile (反过来又使用 Module::Compile 可以 standard caveats on source filters 申请。

        4
  •  1
  •   Chas. Owens    14 年前

    在编写Perl时,可能不应该考虑速度。去吧,让事情正常运转。如果稍后的分析显示由于调用了一个简单的函数而花费了大量时间,那么可以自己内联该函数。