-
Notifications
You must be signed in to change notification settings - Fork 805
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
[WIP] Non-boxing equality for enums (in generic contexts) #930
[WIP] Non-boxing equality for enums (in generic contexts) #930
Conversation
Use magical System.Collections.Generic.EqualityComparer.Default for typeof<_>.IsEnum
Tests try to ensure that the compiler doesn't inline the functionality
Hi @manofstick, I'm your friendly neighborhood Microsoft Pull Request Bot (You can call me MSBOT). Thanks for your contribution! The agreement was validated by Microsoft and real humans are currently evaluating your PR. TTYL, MSBOT; |
To support alternative profiles
@manofstick I can't judge whether this will be a breaking change. My hope is that it's only a performance optimization, right? |
Sorry, I just assumed that anyone reading these would have been familiar with #513 that just recently got merged, so was maybe more brief that I should of been in the description. So yes, it is a performance optimization that sits within the #513 framework. System.Enum derived objects (i.e. enumerations) only derive from ValueType, IComparable, IFormattable & IConvertible. i.e. specifically they don't derive from IEquatable<'a>, which means that the have no type based overload of the Equals method. Used in a generic context then, there are no generic constraints that allow you to test for equality in a non-boxing fashion (unless I am wrong...) #513 was all about building up nice equality operators (and comparison operators) in this generic context for HashIdentity. (When not used in a generic context (including inlining obviously), the fsharp compiler sneakily creates IEqualityComparer<'a> derived objects. And when in generic contexts, FSharp.Core has hard-coded common System types (i.e. int, char, string...)) Anyway, the long and short of it is in code that is compiled using HashIdentity.Structural on a type that isn't fully known at compile time, think (groupBy, dict, ...) then you fall down this path. So yes, some tests were in the scope of the the "non breaking change" that you were after (possibly not exhaustive, I didn't feel the change was particularly meaty), and the bit where I said "non-boxing" was meant to imply that this would put less pressure on the garbage collector, and thus is a performance improvement. When I get home, I'll run some numbers for you. |
@manofstick No need to be sorry, thank you for the great explanation. Looking towards the numbers 👍 |
OK @mexx I have tried to make a semi-realistic (squint, and twist your head a little...) example where we are doing a groupBy on an enum field. The code was compiled from the command line with
where xxx was x32 or x64 as per listed times below
The results:
Where:
NB. Times in the master branch are already significantly better than release due to both #549 and #513 |
Not longer makes sense after #966 |
I'll reopen and mark WIP, we don't want to lose this |
Hi @manofstick, I'm your friendly neighborhood Microsoft Pull Request Bot (You can call me MSBOT). Thanks for your contribution! The agreement was validated by Microsoft and real humans are currently evaluating your PR. TTYL, MSBOT; |
@dsyme Did you change your mind about WIP? I note that it isn't marked WIP. |
...and I don't think it was this one that was meant to be reopened - I think it was supposed to be #961... |
closing and reopening #961 |
Building on the equality framework, this adds non-boxing equality for System.Enum derived objects (i.e. .net enums) via the "trick" of using System.Collections.Generic.EqualityComparer.Default.Equals. The same trick was attempted for the comparison functionality, but the underlying System object was still boxing.