-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Improve Dictionary TryGetValue size/perfomance #27195
Conversation
Thanks @benaadams . Are you going to share microbenchmarks for this one? |
TryGetValue improved significantly
ContainsKey more or less the same
Not much movement on KNucleotide; guess that was mostly coming from dropping modulo
|
A follow up; as @GrabYourPitchforks suggests #27149 (comment) would be to add the helper methods partial class Unsafe
{
internal bool IsNullRef<T>(in T);
internal ref T NullRef<T>();
} Then drop the |
Non-sequential keys are also improved
|
Linux_musl still queued and ci timed out because of it :( |
I would like to see this done as part of this change. Are you sure that it actually needs jit changes? I would expect that the two new Unsafe methods just needs implemented in the IL in getILIntrinsicImplementationForUnsafe. |
src/System.Private.CoreLib/shared/System/Collections/Generic/Dictionary.cs
Outdated
Show resolved
Hide resolved
src/System.Private.CoreLib/shared/System/Collections/Generic/Dictionary.cs
Outdated
Show resolved
Hide resolved
src/System.Private.CoreLib/shared/System/Collections/Generic/Dictionary.cs
Outdated
Show resolved
Hide resolved
Here is a bit of code that you reuse: 9353ac3#diff-bbced44286fd2ad6bcf70fbd3c276d57L7254 Also, I have submitted a proposal to add these two APIs to a public version of Unsafe as well: https://github.com/dotnet/corefx/issues/41783 |
src/System.Private.CoreLib/shared/System/Collections/Generic/Dictionary.cs
Outdated
Show resolved
Hide resolved
Found out where the weird boolean asm output is coming from; is basically the Jit doing as its asked
Can maybe do something like this instead?
/cc @AndyAyersMS |
I think my PR #27167 should improve codegen for this IL if I understand you correctly. |
Might do :) Junky bool handling |
src/System.Private.CoreLib/shared/System/Collections/Generic/Dictionary.cs
Show resolved
Hide resolved
src/System.Private.CoreLib/shared/System/Collections/Generic/Dictionary.cs
Outdated
Show resolved
Hide resolved
I'm having issue with the metasig.h for I've got to
but its not very happy with that; any pointers? |
You shouldn't need to define a metasig since the method doesn't have multiple overloads. Check 9353ac3#diff-027a321a370548745efff3d113085fd6L716, which specifies NoSig to mean "don't bother with signature matching - only match on the name." |
Ah ah! I was trying to work out the rules on how some things had nosig when clearly they did; and how that fit with the other sig rules :) |
src/System.Private.CoreLib/shared/Internal/Runtime/CompilerServices/Unsafe.cs
Outdated
Show resolved
Hide resolved
0007192
to
996524e
Compare
src/System.Private.CoreLib/shared/Internal/Runtime/CompilerServices/Unsafe.cs
Outdated
Show resolved
Hide resolved
Final scores:
|
Plus verify that nothing went awry in the later commits
/cc @mjsabby |
src/System.Private.CoreLib/shared/Internal/Runtime/CompilerServices/Unsafe.cs
Outdated
Show resolved
Hide resolved
src/System.Private.CoreLib/shared/Internal/Runtime/CompilerServices/Unsafe.cs
Outdated
Show resolved
Hide resolved
src/System.Private.CoreLib/shared/System/Collections/Generic/Dictionary.cs
Outdated
Show resolved
Hide resolved
src/System.Private.CoreLib/shared/System/Collections/Generic/Dictionary.cs
Outdated
Show resolved
Hide resolved
840f881
to
3507078
Compare
Co-Authored-By: Jan Kotas <jkotas@microsoft.com>
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.
Thank you!
src/System.Private.CoreLib/shared/Internal/Runtime/CompilerServices/Unsafe.cs
Outdated
Show resolved
Hide resolved
Could you please add the IL for the NullRef and IsNullRef also to https://github.com/dotnet/coreclr/blob/master/src/tools/crossgen2/Common/TypeSystem/IL/Stubs/UnsafeIntrinsics.cs#L72 ? |
Added |
* Dictionary avoid second bounds check in Get methods * Add NullRef methods to Unsafe Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
* Dictionary avoid second bounds check in Get methods * Add NullRef methods to Unsafe Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
* Dictionary avoid second bounds check in Get methods * Add NullRef methods to Unsafe Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
* Dictionary avoid second bounds check in Get methods * Add NullRef methods to Unsafe Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
* Dictionary avoid second bounds check in Get methods * Add NullRef methods to Unsafe Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
* Dictionary avoid second bounds check in Get methods * Add NullRef methods to Unsafe Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
From #27149 without the hashcode-to-bucket mapping changes
ref
rather than an index to TryGetValue/indexer get methods; so a second dip back to the backing array is not needed.ref
from FindValue so ContainsKey doesn't pay a struct copy cost when using same method.Entry
struct to puthashCode
first rather thannext
as it is accessed first which should work with prefetching better.collisionCount++
beforecollisionCount
test so the Jit could micro-fuse them (though doesn't currently https://github.com/dotnet/coreclr/issues/7566)Size improvements
/cc @jkotas @AntonLapounov @GrabYourPitchforks