MoarVM icon indicating copy to clipboard operation
MoarVM copied to clipboard

Huge perf penalty when iterator reaches 2**31-1

Open thibaultduponchelle opened this issue 4 years ago • 2 comments

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

thibaultduponchelle avatar Nov 18 '20 10:11 thibaultduponchelle

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.)

coke avatar Oct 30 '21 01:10 coke

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.

MasterDuke17 avatar Oct 31 '21 23:10 MasterDuke17