Deferencing only once per function call for RangeEnumerator#1532
Deferencing only once per function call for RangeEnumerator#1532KevinRansom merged 1 commit intodotnet:masterfrom
Conversation
|
Actually I'm pretty confused now. Looking at the git history, it was a mutable variable in @manofstick's original implementation, but it was changed to use a |
|
Th F# compiler is compiled with all warnings enabled, including the one for when "let mutable" values are promoted to refs, to help make allocations pain. So a compiler warning would be triggered by your code. |
|
@dsyme I don't see any errors from using the mutable. That said instead of using |
forki
left a comment
There was a problem hiding this comment.
Are there similar functions which use ref cells?
|
@forki, I didn't see any in the same file. I didn't check too hard for other files though. |
|
These look good to me. |
|
This doesn't actually do anything; the "let mutable ..." does just get converted into a ref field, as per @dsyme's comments. I think where the observed speed up comes from is that in 4.4.1.x there is the "singleStepRangeEnumerator" optimization which I did a while back (which I guess I thought already existed in the 4.4.0.x codebase... Seemed like a long time ago!) Anyway, it appears that my original gist was a bit of a red herring. I still think that seq {} blocks should drag the iteration into the state machine, rather than deferring it to the helper enumerable, but the effect of this is obviously not as bad as it had once been. I think this PR should just be closed. |
|
@manofstick You're right the mutable doesn't do anything in reality. The emitted IL is effectively the same. However, I think if we were to make the relevant function only dereference once per function call, we would in fact get some savings. Here's some of my results (note that the new Range is marginally slower for
Here is the gist for that test: https://gist.github.com/liboz/c9e529d0292f25135243721157b93fae |
|
(...to ensure consumption of "Current", you should probably change Anyway, no detrimental effects, and bit of a kick with x86, so why not? |
|
❤️ |
|
(off-topic) Hey @forki, do you have like a performance comparison of the last releases of F# versus the current master? Just as a summary. It feels like a lot have been implemented lately? |
Thanks to @manofstick's test gist, I found out that one major slowdown for his test case was because of dereferencing. This PR switches to using a mutable variable instead of dereferencing multiple times. It makes the state machine more comparable to his test case (2x slower for 64bit and slightly faster for 32bit), those translate to a 3x speed increase for 64bit and a 7x for 32bit