Skip to content
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

Consider creating new dictionary type which allocates an array for small capacities instead of an entire dictionary #31290

Closed
jkotalik opened this issue Mar 26, 2021 · 8 comments
Assignees
Labels
area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions Perf
Milestone

Comments

@jkotalik
Copy link
Contributor

We allocate a lot of dictionaries across ASP.NET Core, which have a non-zero allocation cost to them. An interesting idea would be to see if we could use an array internally for smaller sizes.

We already do this today in Routing: https://github.com/dotnet/aspnetcore/blob/main/src/Http/Http.Abstractions/src/Routing/RouteValueDictionary.cs. I think we could probably use RouteValueDictionary (or a copy of it) in different places across the stack.

@jkotalik
Copy link
Contributor Author

Confirmed that RouteValueDictionary allocates less bytes by default than a Dictionary (40 bytes vs 66 bytes). @JamesNK thoughts on using RouteValueDictionary in more places where we expect small amounts of values in a dictionary?

@blowdart
Copy link
Contributor

Be careful to check it's protected against hash collision attacks if any user data goes near it.

@BrennanConroy BrennanConroy added this to the Next sprint planning milestone Mar 26, 2021
@ghost
Copy link

ghost commented Mar 26, 2021

Thanks for contacting us.
We're moving this issue to the Next sprint planning milestone for future evaluation / consideration. We will evaluate the request when we are planning the work for the next milestone. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

@halter73
Copy link
Member

Kestrel's IFeatureCollections use a List<KeyValuePair<Type, object>>? MaybeExtra which is better than Dictionary for small sets, but those might be a good candidate for this.

@JamesNK
Copy link
Member

JamesNK commented Mar 26, 2021

The concept you're interested in with RouteValueDictionary is fine - an array backed dictionary for small numbers of values.

The actual RouteValueDictionary implementation probably shouldn't be exactly reused because it also supports a dictionary of property values, i.e. new RouteValueDictionary(new { hello = "world" }), which most places don't need.

@JamesNK
Copy link
Member

JamesNK commented Mar 26, 2021

Be careful to check it's protected against hash collision attacks if any user data goes near it.

No hashing involved. Keys are matched by looping over all the items in the dictionary. O(n) world.

@blowdart
Copy link
Contributor

Ah hence for "very small" collections :)

@jkotalik
Copy link
Contributor Author

The actual RouteValueDictionary implementation probably shouldn't be exactly reused because it also supports a dictionary of property values, i.e. new RouteValueDictionary(new { hello = "world" }), which most places don't need.

Yeah, I did a quick test with RouteValueDictionary and it seemed to be fine, but agree we should create a new type.

@jkotalik jkotalik self-assigned this Mar 27, 2021
@jkotalik jkotalik closed this as completed Apr 7, 2021
@ghost ghost locked as resolved and limited conversation to collaborators May 14, 2021
@amcasey amcasey added area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions and removed area-runtime labels Aug 24, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions Perf
Projects
None yet
Development

No branches or pull requests

6 participants