MoarVM
MoarVM copied to clipboard
Huge perf penalty when iterator reaches 2**31-1
This code runs in 15 seconds :
for (1..2147483646) { }
But this same code with 1 more iteration takes 16 minutes :fearful: :
for (1..2147483647) { }
I understand there is some "unboxing" or storage related stuff that allows this difference, but is there a way to improve this situation ? (Without to mention that it is an empty loop...)
Using explicit uint64
native type does not help :
for (1..2**31) -> uint64 $item { }
Feel free to close this issue if you consider it is "by design".
Thibault
v2021.10-23-gc50bc9985 on macos11.6 runs these two in 27s and 1m55s - so, an improvement in the relative speed, but still 4x slower (and as you say, they are empty loops and surely we can do better there.)
This happens because 2147483647 is the cutoff (https://github.com/rakudo/rakudo/blob/master/src/Perl6/Optimizer.nqp#L1215) where iterating a range can't be optimized (https://github.com/rakudo/rakudo/blob/master/src/Perl6/Optimizer.nqp#L2498-L2579). 2147483647 is probably the cutoff because that's the value below which an integer is stored as a plain C int, instead of a biginteger (https://github.com/MoarVM/MoarVM/blob/master/src/6model/reprs/P6bigint.h#L5). I'm not saying we can't do better, just explaining what I think is happening right now.