代码之家  ›  专栏  ›  技术社区  ›  varnie

Perl内部和Moose:持续折叠优化

  •  4
  • varnie  · 技术社区  · 11 年前

    我一直对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)

    1 回复  |  直到 11 年前
        1
  •  8
  •   amon    11 年前

    这与驼鹿无关。在里面

    $x + 32 - 8
    

    评估顺序相当于

    ($x + 32) - 8
    

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

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

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

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

    这个 perlguts 文档常量折叠,并具体说明它通过替换树的部分来操作。