Debugging some code ended up testing the differences in the statements such as $counter=$counter + 1;
vs $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)}"; #
}
I'm getting around 20% more iterations per second for $counter=$counter+1
compared to $counter+=1;
Whats happening in the background thats so different?
EDIT:
Interestingly when trying this with an array and hyper operators the performance is greatly increased when using the +=
.
eg
@counter=@counter>>+<<@value;
vs
@counter>>+=<<@value;
I get about 2.8 times the iterations of the loop using >>+=<<
with arrays of 10_000 elements.
As far as I can tell via the time
cmd there is minimal parallel execution in either case (total user + system is within 2% of real time).
Any insight on how/why this is would be great. Thanks!
I've golfed your benchmark to:
my $a = 0; for ^10_000_000 { $a += 1 }
vs:
my $a = 0; for ^10_000_000 { $a = $a + 1 }
If you run these examples in the profiler with perl6 --profile -e '...'
, then you'll see that the difference is indeed in the 20% range. The only thing that is really different, is the total number of frames: 49935579 for += 1
, and 39932197 for = $a + 1
.
The underlying difference (before any optimizations), is that +=
goes through a metaop path. It is not defined as a separate operator, so it needs to create the operator on the fly, taking the original operator (&infix:<+>
) as a parameter and building a Callable
out of that.
FWIW, I'm glad to see the difference is only 20% nowadays: it wasn't too long ago when anything involving metaops was at least 2x as slow :-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With