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-8のだろうか24? Perl がそうしなかった本当の理由はありますか?

役に立ったら、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 に答える