- Notifications
You must be signed in to change notification settings - Fork5.2k
Add CollectionsMarshal.GetValueRefOrAddDefault#54611
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Add CollectionsMarshal.GetValueRefOrAddDefault#54611
Uh oh!
There was an error while loading.Please reload this page.
Conversation
ghost commentedJun 23, 2021
Note regarding the This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, to please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change. |
ghost commentedJun 23, 2021
Tagging subscribers to this area:@eiriktsarpalis Issue DetailsContributes to#27062namespaceSystem.Runtime.InteropServices{publicstaticrefTValue?GetValueRefOrAddDefault<TKey,TValue>(Dictionary<TKey,TValue>dictionary,TKeykey,outboolexists)whereTKey:notnull;}}
|
src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs OutdatedShow resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
Sergio0694 commentedJun 24, 2021
@jkotas Could you clarify what the overhead of this new method would be, and whether it would be a blocker for this PR? This would be a very neat feature to have, and the API itself has been approved by API review too - if it's just the current implementation that's an issue would any of the proposed approaches help? As in, moving the code to a diferent spot, etc. Thanks! 🙂 |
jkotas commentedJun 24, 2021
It makes every Dictionary instantiation more expensive, in particular with AOT. |
Sergio0694 commentedJun 24, 2021
I see. If the issue is specifically with the overhead of dictionary instantiations, would moving the code to a separate type (eg. a nested type within dictionary) solve that? That would only ever be loaded when the method is actually used, right? 🤔 |
jkotas commentedJun 24, 2021
Yes, it would solve that. |
8b9e772 to31d7120Compare31d7120 to99523baCompareSergio0694 commentedJul 9, 2021
Test failures should be unrelated, and the changes in99523ba addresses Jan's concerns on additional overhead being added to |
99523ba to5367083Compare
GrabYourPitchforks 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.
@Sergio0694 Thanks for this! Can you also add a unit test for the randomized hash logic? I think the appropriate place to add this would be in the filehttps://github.com/dotnet/runtime/blob/main/src/libraries/System.Collections/tests/Generic/Dictionary/HashCollisionScenarios/OutOfBoundsRegression.cs.
There's no need to modifyRunDictionaryTest (line 93 of that file) to run aCollectionsMarshal test for every possible combination; that's probably overkill. Instead, what you can do is immediatelybefore line 93, insert a manual call that looks something like:
RunCollectionTestCommon(()=>newDictionary<string,object>(StringComparison.Ordinal),(dictionary,key)=>CollectionsMarshal.GetRef(dictionary,key,out_)=null,(dictionary,key)=>dictionary.ContainsKey(key), dictionary=>dictionary.Comparer,expectedInternalComparerTypeBeforeCollisionThreshold:nonRandomizedOrdinalComparerType,expectedPublicComparerBeforeCollisionThreshold:StringComparer.Ordinal,expectedInternalComparerTypeAfterCollisionThreshold:randomizedOrdinalComparerType);
In a nutshell, this utilizes the existing test infrastructure to generate a whole bunch of collisions, but the delegate you provide will force it to use your newCollectionsMarshal method instead ofAdd. This will get regression test coverage for string collision scenarios in this method.
src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs OutdatedShow resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/CollectionsMarshal.cs OutdatedShow resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
This avoids the additional overhead when loading Dictionary<TKey, TValue> instances, especially in AOT scenarios, and it makes the new API pay for play.
5367083 to1d7e386Compare...stem.Runtime.InteropServices/tests/System/Runtime/InteropServices/CollectionsMarshalTests.cs OutdatedShow resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
...stem.Runtime.InteropServices/tests/System/Runtime/InteropServices/CollectionsMarshalTests.csShow resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
eiriktsarpalis 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.
Other than minor feedback, LGTM. Thanks!
GrabYourPitchforks commentedJul 14, 2021
A reminder for the future - try to avoid rebase & force-push after reviews have started. Makes it a little more complicated for us since we can't rely on the GitHub web UI and instead we need to generate incremental diffs manually. |
Sergio0694 commentedJul 14, 2021
Oh, I'm sorry, I didn't realize that. Will definitely avoid doing that again in the future! 😅 |
GrabYourPitchforks 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.
Thanks so much! :D
Uh oh!
There was an error while loading.Please reload this page.
Contributes to#27062