为什么性能差异在+ = vs +?

问题描述 投票:14回答:1

调试一些代码最终测试了语句中的差异,例如$counter=$counter + 1;$counter+=1;

my $run=True;
my $counter=0;
my $sup=Supply.interval(1);
my $tap= $sup.tap({
    $run=$_ < 10;
});
{
    while $run {
        #$counter+=1;
        $counter=$counter + 1;
    }
    $tap.close;
    say "Iterations per second: {$counter/(now - ENTER now)}"; #
}

$counter=$counter+1相比,$counter+=1;的每秒迭代次数增加了约20%

在背景中发生的事情是如此不同?

编辑:

有趣的是,当使用数组和超级运算符进行尝试时,使用+=时性能会大大提高。

例如@counter=@counter>>+<<@value; vs @counter>>+=<<@value;我使用带有10_000个元素的数组的>>+=<<获得了大约2.8倍的循环迭代次数。

据我所知,通过time cmd,在任何一种情况下都有最小的并行执行(总用户+系统在实时的2%之内)。

任何有关如何/为何如此的见解都会很棒。谢谢!

perl6
1个回答
16
投票

我把你的基准打到了:

my $a = 0; for ^10_000_000 { $a += 1 }

VS:

my $a = 0; for ^10_000_000 { $a = $a + 1 }

如果您使用perl6 --profile -e '...'在探查器中运行这些示例,那么您将看到差异确实在20%范围内。唯一真正不同的是框架总数:+= 1为49935579,= $a + 1为39932197。

潜在的差异(在任何优化之前)是+=经历了一个metaop路径。它没有被定义为单独的运算符,因此它需要动态创建运算符,将原始运算符(&infix:<+>)作为参数并从中构建Callable

FWIW,我很高兴看到现在差异只有20%:不久之前,任何涉及metaops的事情都至少有2倍的速度:-)

© www.soinside.com 2019 - 2024. All rights reserved.