Perl internals and Moose: constant-folding optimization

╄→尐↘猪︶ㄣ 提交于 2019-12-22 09:40:02

问题


I've been curious about constant-folding optimizations which Perl performs, but it occurred that when the code has Moose involved chances are that constant-folding won't be performed (please correct me if I am wrong).

I have Moose code which contains the method as below:

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();
    }
    #...
}

and when I run perl -MO=Deparse ./program.pl I get almost identical code line:

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();
}

I wonder why Perl didn't optimize 32-8 as 24? Are there any real reasons Perl didn't do that (maybe Moose subsystem makes the life harder?).

If it helps, I run Perl (v.5.14.2)


回答1:


This has nothing to do with Moose. In

$x + 32 - 8

the evaluation order is equivalent to

($x + 32) - 8

(i.e. + and - have same precedence level and are left-associative). As a tree:

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

No part of that syntax tree has only constant nodes: $x + 32 isn't constant, and PREVIOUS_PART - 8 isn't constant either. Therefore, the constant folding (which only operates at this tree level, and can't reorder parts of the tree) doesn't see any chances for optimizations.

You do get the optimization of you reorder to 32 - 8 + $x.

The perlguts document constant folding, and specifically state that it operates by substituting parts of the tree.



来源:https://stackoverflow.com/questions/18579505/perl-internals-and-moose-constant-folding-optimization

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!