我一直对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 我得到了几乎相同的代码行:
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子系统让生活变得更艰难了?)。
32-8
24
如果有帮助的话,我运行Perl(v.5.14.2)
这与驼鹿无关。在里面
$x + 32 - 8
评估顺序相当于
($x + 32) - 8
(即。 + 和 - 具有相同的优先级并且是左关联的)。作为一棵树:
+
-
(-) / \ (+) 8 / \ $x 32
该语法树的任何部分都没有只有常量节点: $x + 32 不是恒定的,并且 PREVIOUS_PART - 8 也不是恒定的。因此,常量折叠(仅在该树级别操作,不能对树的部分进行重新排序)看不到任何优化的机会。
$x + 32
PREVIOUS_PART - 8
您确实得到了重新排序的优化 32 - 8 + $x .
32 - 8 + $x
这个 perlguts 文档常量折叠,并具体说明它通过替换树的部分来操作。