❔ Excessive runtime allocation using Dictionary with struct key TryGetValue
Doing some optimization testing using spatial partitioning of 2D scenes and have hit a weird runtime allocation problem that I've tracked down to Dictionary.TryGetValue.
I am storing Chunk instances in a Dictionary with a custom int2 struct type that implements IEquatable.
Here's my index type:
Any tips to fix or avoid this?
6 Replies
Off the top of my head, maybe try overriding the GetHashCode?
we probably need some info to understand this problem
like how big is the dictionary, where are you using ChunkCoord (are you saying it's the key?), what are your expectations, also why struct and not class
yeah, the perf capture shows that ChunkCoord is TKey, and TValue is...
System.__Canon
The hell is System.__Canon
?
yes, you very much should be overriding Equals() for anything that implements IEquatable<>, and you should be overriding GetHashCode() for anything that overrides Equals().
Alternatively, just make the whole struct a record struct.
However, I feel like we're still missing something from that perf capture. Do you have an option set to have it stop tracking calls as soon as it hits an external call? Cause if the problem is your stuct implementation, you should be seeing Dictionary<>.TryGetValue() hop BACK into your own code for at least a .Equals() call.
Otherwise, I'd have to say that this profile shows the allocations have nothing to do with the struct, and are somehow occurring within .TryGetValue() itself. Like it's allocating arrays for intermediate results or something.__Canon
is a stand-in for a reference type
the problem here is almost certainly that GetHashCode
is not overridden, yes
the default implementation of it for a struct is not good. it is slow and results in frequent collisions. it also requires that the struct is boxed, which is almost certainly the source of the allocations
that is why the allocations show up in TryGetValue and not elsewhere. calling .GetHashCode()
itself requires an allocation
i agree that nicely solves this issuethat'll do it, then
for reference, the proper way to write your own
GetHashCode()
method, if you ever need to is...
at least, starting with .NET Core 2.1Was this issue resolved? If so, run
/close
- otherwise I will mark this as stale and this post will be archived until there is new activity.