-
Notifications
You must be signed in to change notification settings - Fork 842
Deferencing only once per function call for RangeEnumerator #1532
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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