4

我一直对 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-8as 24?Perl 没有这样做有什么真正的原因吗(也许 Moose 子系统让生活变得更艰难?)。

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

4

1 回答 1

8

这与穆斯无关。在

$x + 32 - 8

评估顺序相当于

($x + 32) - 8

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

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

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

你确实得到了你重新排序的优化32 - 8 + $x

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

于 2013-09-02T19:18:40.607 回答