Почему разница в производительности в + = против +?
Отладка некоторого кода закончилась проверкой различий в утверждениях, таких как $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)}"; #
}
Я получаю примерно на 20% больше итераций в секунду для $counter=$counter+1
по сравнению с $counter+=1;
Что происходит на фоне, это так по-другому?
РЕДАКТИРОВАТЬ:
Интересно, что при использовании массива и гипероператоров производительность значительно увеличивается при использовании +=
.
например, @[email protected]>>+<<@value;
vs @counter>>+=<<@value;
Я получаю примерно 2,8 раза итераций цикла, используя >>+=<<
с массивами из 10_000 элементов.
Насколько я могу судить по time
cmd, минимальное параллельное выполнение в любом случае минимально (общее количество пользователей + система находится в пределах 2% от реального времени).
Любое понимание того, как/почему это было бы здорово. Спасибо!
Ответы
Ответ 1
Я показал ваш тест на:
my $a = 0; for ^10_000_000 { $a += 1 }
против:
my $a = 0; for ^10_000_000 { $a = $a + 1 }
Если вы запустите эти примеры в профилировщике с помощью perl6 --profile -e '...'
, то вы увидите, что разница действительно находится в диапазоне 20%. Единственное, что действительно отличается, - это общее количество кадров: 49935579 для += 1
и 39932197 для = $a + 1
.
Основное различие (до каких-либо оптимизаций) заключается в том, что +=
проходит через метаопуть. Он не определен как отдельный оператор, поэтому ему нужно создать оператор на лету, взяв в качестве параметра исходный оператор (&infix:<+>
) и Callable
из него Callable
.
FWIW, я рад видеть, что в настоящее время разница составляет всего 20%: это было не так давно, когда что-либо, включающее метаопы, было как минимум в 2 раза медленнее :-)