-
Notifications
You must be signed in to change notification settings - Fork 10.3k
Avoid allocating the CandidateSet when there's a single match #9622
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
Conversation
- Add fast path for 0 route values, and policies
@@ -24,7 +24,7 @@ public sealed class EndpointSelectorContext : IEndpointFeature, IRouteValuesFeat | |||
/// </summary> | |||
public RouteValueDictionary RouteValues | |||
{ | |||
get => _routeValues; | |||
get => _routeValues ?? (_routeValues = new RouteValueDictionary()); |
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.
If we're going to do this, we can take advantage of it in more cases, including the ones that involve cnadidate set.
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.
This is beyond the scope of this PR, but what about reusing RVD instances? It would be similar to how we're reusing HttpContext et al. It's basically a per-request allocation that is tied to the route values feature.
Reusing RVD, and the routing feature, would save allocations on every request, not just those with no route values.
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.
We can just straight up do this in Kestrel I fear we won't be able to do the more generic caching for 3.0
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.
If we're going to do this, we can take advantage of it in more cases, including the ones that involve cnadidate set.
Yes, we can, I just wanted to minimize the code change for now. I have to look at see what things are assuming route values are never null when looking at CandidateState.RouteValues (maybe I can do it statiaclly with #enable nullable 😄 )
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.
CandidateSet has some special semantics around RVD that should just be removed. If treats null RVD as a shorthand for not-a-match in some APIs.
####?s |
Will get some. I went awaty but now I'm back |
|
||
public DfaMatcher(ILogger<DfaMatcher> logger, EndpointSelector selector, DfaState[] states, int maxSegmentCount) | ||
{ | ||
_logger = logger; | ||
_selector = selector; | ||
_states = states; | ||
_maxSegmentCount = maxSegmentCount; | ||
_isDefaultEndpointSelector = selector is DefaultEndpointSelector; |
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.
I'd feel slightly better if this was an exact type equality check. This isn't public, but that would capture the intent better.
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 it sealed? Future proofing?
Scenario, hello world plaintext (the /plaintext sample in the RoutingSandbox) hit with 10K requests.
Allocations before:
Allocations after:
Microbenchmarks:
MatcherSingleEntryBenchmark
Before:
After: