-
Notifications
You must be signed in to change notification settings - Fork 38.3k
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 attribute handling in RequestPredicates #30028
Improve attribute handling in RequestPredicates #30028
Conversation
2f8c06d
to
06a5631
Compare
Interesting. I will take a closer look for 6.1 M1. |
@poutsma Thanks, here is some background. I have a few dozen routes registered like so: RouterFunctions.Builder builder = RouterFunctions.route();
builder.add(RouterFunctions.route(RequestPredicates.GET("/foo"), fooHandler));
builder.add(RouterFunctions.route(RequestPredicates.GET("/bar"), barHandler));
....
return builder.build(); and I collected this memory icicle graph: The saving and restoring uses the majority of the memory and cpu relative to the actual evaluation of the HttpMethodPredicate and PathPatternPredicate My handlers dont use much cpu or memory, so this was constituting an non-negligible percentage of the applications overall footprint. |
Here are some more extensive icicle graphs generated from my stress test. memory before (the selected item is basically all of the "memory after" graph): and i have two more optimizations within that which should cut down even more: #30138 and #30139 |
@yuzawa-san Great work, thanks! |
06a5631
to
acbe050
Compare
acbe050
to
4046b9f
Compare
4046b9f
to
f4158d3
Compare
f4158d3
to
d6c6f4e
Compare
There was a lot of copying of the attributes map in the AND/OR/NOT predicates which I believe can be avoided.
d6c6f4e
to
abf6227
Compare
This PR has now been merged, though I did some refactoring and renaming. Thank you for your contribution! |
* gh-30028: Polishing external contribution Improve attribute handling in RequestPredicates
I was doing some memory allocation flame chart analysis and found that there was a lot of copying of the attributes map in the AND/OR/NOT predicates which I believe can be avoided. The intent appeared to be to support the PathPatternPredicate which is the only implementation that updates the request state. Given that the PathPatternPredicate can be embedded within any number of boolean operators the save, evaluate, and restore operation was added in those predicates.
The solution I had was to introduce some additional classes which allow for the predicate to make changes. This is the
Evaluation
record which has the test result and whatever state changes should be done if the caller deems it so.Open question: the PathPatternPredicate appeared to be the only implementation which updated the request, but do folks have state-modifying predicates out in the wild? It would appears physically possible, but at the same time against the
@FunctionalInterface
nature of the definition of RequestPredicate. So this could break extant use cases, but those use cases are not necessarily philosophically correct. Given PathPatternPredicate is internal (and "rule breaking" by changing state), I supposed internally we could support its rule breaking.The existing RequestPredicateAttributesTests all pass still.
I only did the changes in webflux, but could port these changes over to the servlet functions as well later if this is accepted.