Use range for instead of next in fold - #455
Conversation
Allows the compiler to optimise more by giving it extra information to work with, namely giving it proper length information instead of hoping it peeks through repeated while let calls. By all rights it should be able to optimise without this change but possibly due to some non-optimal optimisation ordering it doesn't end up being able to vectorize loops.
Out of curiosity, do we actually see that in the output?
Given that the overwhelming majority of applications won't benefit, I'm reluctant to broadly recommend a much less ergonomic pattern. |
|
The for_each 100k benchmark has much higher improvement on my device: from 168.9us to 8.14us, which is around 95% percent time decrease ! The performance improvement is not only due to SIMD, but also the reduced branches. The next() based method has 2 branches per item while the for-range based only has 1 branch per item. Hoping to see this published into crates.io soon. |
My mistake, this improvement is actually due to #436 |
Another interesting point is that this result is tested when using |
Related (but doesn't fix): #351
Allows the compiler to optimise more by giving it extra information to work with, namely giving it proper length information instead of hoping it peeks through repeated while let calls.
By all rights it should be able to optimise without this change but possibly due to some non-optimal optimisation ordering it doesn't end up being able to vectorize loops, even though it inlines everything to essentially a range for in the end.
The for_each 100k benchmark goes from 100 µs to 22 µs on my system, about a 4x speedup (which tracks with using 128-bit SIMD instructions). Now this is a very contrived benchmark and I suspect actual gains will be much less impactful, but might as well..?
This doesn't change the speed of the iterate mut 100k benchmark, which doesn't use fold (perhaps there should be more documentation explaining that fold/for_each should be used when possible).