-
Notifications
You must be signed in to change notification settings - Fork 790
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
Ranges allocate 670 MB in 94 seconds of normal IDE usage in service.fs only #6047
Comments
More general issue here: #526 But this is a rather pressing issue with data. |
Wow, this may well be at the root of many of the heap alloc issues we have, I can imagine this also happens with many more types. Can the generic comparer be written in a way to avoid boxing? |
I'm not sure the function is inherently bad. The fact that F# structs are boxed if they are defined with What's ironic is that these structs are boxed, only to end up calling an overridden |
After an intense night with Optimizer.fs, I managed to output the Related topics: @manofstick I'm now walking down your path and I see the demons you had to come across. |
Quoting from @dsyme #513 (comment) :
|
hahah. Yeah in all production code where I use value types, I give them CustomEquality just so I can override the boxing Equals operator and throw an exception in it to find all uses!! Anyway, #5307 is a good PR (if I do say so myself!) It should be 100% compatible with existing code - and although not quite as as optimal as outputting IEquatable's Equals, it's non-boxing, and pretty good. There is a slight initial runtime cost (to use reflection) but then gone. And the benefit has over compiler injection is that it works for generic code - think collection classes at a bare minimum. and eventually you could modify the compiler to follow the same rules (i.e. scour the type definitions to determine what sort of equality is required)... |
@manofstick I need to look at your PR a bit more. I am curious how you avoid boxing when the first call to equality is |
magic |
I modified the compiler in some places, but there were others where I didn't, so possibly it doesn't it the cases you actually care about. I can't remember what it does actually. Been too long :-) |
Slowing memories are creeping - I think the reason the compiler put in the |
So, the fundamental problem is that we don't have However, F# defined records, unions, and struct types (without As soon as you do For this issue in particular with ranges, the solution without potentially harming equality in F# is to just make a function call to check range equality instead of using |
Closing as we merged the PR to resolve this issue. A long term solution would be to devirtualize |
Ranges are a struct, so it's strange that it would show up so high in the GC stats:
Taking a look, this is mostly due to equality comparisons:
Range is compared all over the place with
=
and<>
. This actually leads towardsGenericEqualityIntrinsic
, which causes boxing:https://github.com/Microsoft/visualfsharp/blob/32251218913b82390b6b11e374ea5ac84c2c56ad/src/fsharp/FSharp.Core/prim-types.fs#L1539-L1540
And this leads to lots of heap allocations.
The text was updated successfully, but these errors were encountered: