【问题标题】:Perl internals and Moose: constant-folding optimizationPerl 内部结构和 Moose:常量折叠优化
【发布时间】:2013-09-05 22:24:43
【问题描述】:

我一直对 Perl 执行的常量折叠优化感到好奇,但是当代码涉及 Moose 时,可能不会执行常量折叠(如果我错了,请纠正我)。

我有 Moose 代码,其中包含以下方法:

sub foo {
    my ($self) = shift;
    my $test_y = $self->pos->[1];
    #...
    if ($self->is_map_val($self->pos->[0]+8, $test_y+32) ||
        $self->is_map_val($self->pos->[0]+32-8, $test_y+32)) { 
    {
        heavy_stuff();
    }
    #...
}

当我运行 perl -MO=Deparse ./program.pl 时,我得到几乎相同的代码行:

if ($self->is_map_val($self->pos->[0] + 8, $test_y + 32) or    
    $self->is_map_val($self->pos->[0] + 32 - 8, $test_y + 32)) 
{
    heavy_stuff();
}

我想知道为什么 Perl 没有将 32-8 优化为 24? Perl 没有这样做有什么真正的原因(也许 Moose 子系统让生活变得更艰难?)。

如果有帮助,我会运行 Perl (v.5.14.2)

【问题讨论】:

    标签: perl moose internals constantfolding


    【解决方案1】:

    这与 Moose 无关。在

    $x + 32 - 8
    

    求值顺序等价于

    ($x + 32) - 8
    

    (即+- 具有相同的优先级并且是左关联的)。作为一棵树:

        (-)
        / \
      (+)  8
      / \
    $x   32
    

    该语法树的任何部分都没有只有常量节点:$x + 32 不是常量,PREVIOUS_PART - 8 也不是常量。因此,常量折叠(仅在此树级别运行,不能对树的部分重新排序)看不到任何优化机会。

    您确实得到了优化,您重新订购到32 - 8 + $x

    perlguts 文档常量折叠,并特别声明它通过替换树的部分来操作。

    【讨论】:

    • 谢谢你,它有很大帮助。但就我而言,我没有重载加法运算符。
    • @varnie 我忘记了 Perl 并不介意为常量折叠而重载。它只是常量折叠实现方式的一个实现细节。它只是没有看到32 - 8 是恒定的
    猜你喜欢
    • 1970-01-01
    • 2023-04-04
    • 2021-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-29
    • 2021-08-01
    • 1970-01-01
    相关资源
    最近更新 更多