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)

有帮助吗?

解决方案

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.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top