-
Notifications
You must be signed in to change notification settings - Fork 4k
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
Improve OrderPreservingMultiDictionary. #11254
Improve OrderPreservingMultiDictionary. #11254
Conversation
CyrusNajmabadi
commented
May 11, 2016
- Support allocation-free enumeration of the dictionary.
- Pool internal data so that less garbage is churned when creating and releasing dictionaries.
1. Support allocation-free enumeration of the dictionary. 2. Pool internal data so that less garbage is churned when creating and releasing dictionaries.
tagging @dotnet/roslyn-ide @dotnet/roslyn-compiler The IDE would like to use this API to have a multidictionary that has low memory churn characteristics. Problems with the current API were that:
This PR addresses both these concerns. |
// the single item already in _value, and to store the item we're adding. | ||
// In general, we presume that the amount of values per key will be low, so this | ||
// means we have very little overhead when there are multiple keys per value. | ||
private static ObjectPool<ArrayBuilder<V>> s_builderPool = new ObjectPool<ArrayBuilder<V>>( |
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.
Isn't there a pooled version of array builder? e.g. ArrayBuilder<V>.GetInstance()
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.
Nice catch! I've switched to using that instead!
/// Each value is either a single V or an <see cref="ArrayBuilder{V}"/>. | ||
/// Never null. | ||
/// </summary> | ||
private readonly object _value; |
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.
Is it common to have multiple items with the same key? If not, consider using OneOrMany<T>
instead, which stores the values as T
or ImmutableArray<T>
.
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.
Is that any better though? In the current model, 1, 2, and many are handled fine. In the OneOrMany case, the moment you go past 2, you're always going to allocate on each subsequent add.
LGTM, after the noted change to use an existing pool. |
{ | ||
get | ||
{ | ||
Debug.Assert(this.Count >= 1); |
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.
Is it common to fetch same "Items" twice?
Perhaps it is worth storing the array once it is created. (array can be dropped when set is modified).
LGTM. |