Conversation
Signed-off-by: Matt Klein <mklein@lyft.com>
|
Here is a perf delta between the old header map and the new one on the benchmark: There is definitely a cost for the new implementation as it involves some more cycles of indirection to look up various pieces of data, and a few more virtual calls. I can likely run some of this through callgrind and optimize it some more. Overall though I think the cost is likely worth it given the cleanup and the opportunity to have more custom headers, and compile out custom headers that the user doesn't care about. Note that there is further cleanup work I want to do including removing more default headers and moving them into extensions as well as making the route header add/remove functions pre-lookup O(1) headers and use those if they are defined instead of the O(N) versions. I also want to add some printing of registered headers and sizes at server startup. I will do that on this PR before we finalize it. @jmarantz I wanted to get some initial feedback of this refreshed code though. I have fixed all the previous comments and the impl is even simpler now. |
|
Thanks for fleshing this out! Should we also try a pure flat_hash_map with int-ordered entries just to see what perf looks like there as well, a well as try to compare in one table the performance of this vs the lazy-map variants described in https://docs.google.com/document/d/1yxyRODqaLwMyzBGRkzF_6DJGCGfp4nfjzkUIhtQ8Tc0/edit and prototyped in #9261 ? |
The issue with ^ is that IMO to do it justice we need to flesh out the benchmarks we have quite a bit, to account for the different perf profiles that we expect to see with the different implementations (e.g. re-ordering on encoding, possibly maintaining a linked hash map, building the lookaside map, etc.). My preference would be to land this as we understand the perf profile, it will improve perf in certain cases, and the perf degradation above over the existing impl is on the order of single digit nanoseconds per operation. After that I can start poking at some other stuff in my spare time. WDYT? If we feel that want to compare this with the other potential implementations that will take a lot more time. |
|
I agree that having a comprehensive suite that evaluates the best strategy across realistic use-cases is out-of-scope. I was just thinking about getting a matrix of results for the existing speed tests. @htuch would be interested in your take here too. |
|
Looks cleaner to me, and more readable, thanks! |
|
Yeah, I think landing this is totally fine as an immediate step. I'd love to see the |
|
I'm willing to work on additional implementations and benchmarks after I land this, but if we agree that we can land this now that would avoid it going out of date as we do that. Since it sounds like we agree, I will finish the PR and get it into its final state, but PTAL now and lmk if you have any major comments. |
jmarantz
left a comment
There was a problem hiding this comment.
I confess I haven't been through this in detail but I gave a first pass. I don't think I'll be able to take another look today as my schedule is tight, but I'll try to pour over it this weekend.
Just some small notes so far.
Signed-off-by: Matt Klein <mklein@lyft.com>
|
@jmarantz this should be ready for final review. |
adisuissa
left a comment
There was a problem hiding this comment.
Seems good to me, just added a question.
jmarantz
left a comment
There was a problem hiding this comment.
Overall this looks great. Would you consider adding a header_map.md file to describe the architecture, data structure diagram, threading model, life-of-a-custom-header, etc?
A few minor perf/commenting nits.
Yes will do. |
Signed-off-by: Matt Klein <mklein@lyft.com>
|
@jmarantz updated PTAL and lmk if you want to see anything else in the markdown file. |
| const auto http_response_status = Http::Utility::getResponseStatus(*headers); | ||
| const auto grpc_status = Common::getGrpcStatus(*headers); | ||
| callbacks_.onReceiveInitialMetadata(end_stream ? std::make_unique<Http::ResponseHeaderMapImpl>() | ||
| callbacks_.onReceiveInitialMetadata(end_stream ? Http::ResponseHeaderMapImpl::create() |
There was a problem hiding this comment.
clang-tidy doesn't like the pre-existing std::move of headers below, followed on line 115 by a reference to the moved object. I'm guessing you'll want to fix this somehow; maybe by holding a ref in a temp?
There was a problem hiding this comment.
I added a TODO below. This is a pre-existing bug and I would rather not fix this in this change.
jmarantz
left a comment
There was a problem hiding this comment.
looks great, thank you!
Test added by envoyproxy#11414 uses RequestHeaderMapImpl constructor made private in envoyproxy#11546 Signed-off-by: Florin Coras <fcoras@cisco.com>
Implement custom O(1) header registration for header maps. - Remove virtual inheritence from header maps. - Implement variable inline storage for concrete header maps. - Various TODO/logic cleanups from previous header refactors. - Demonstrate what custom header registration looks like for the CORS filter. More cleanup of this type can be done. Signed-off-by: Matt Klein <mklein@lyft.com> Signed-off-by: yashwant121 <yadavyashwant36@gmail.com>
Test added by envoyproxy#11414 uses RequestHeaderMapImpl constructor made private in envoyproxy#11546 Signed-off-by: Florin Coras <fcoras@cisco.com> Signed-off-by: yashwant121 <yadavyashwant36@gmail.com>
Implement custom O(1) header registration for header maps. - Remove virtual inheritence from header maps. - Implement variable inline storage for concrete header maps. - Various TODO/logic cleanups from previous header refactors. - Demonstrate what custom header registration looks like for the CORS filter. More cleanup of this type can be done. Signed-off-by: Matt Klein <mklein@lyft.com>
Test added by envoyproxy#11414 uses RequestHeaderMapImpl constructor made private in envoyproxy#11546 Signed-off-by: Florin Coras <fcoras@cisco.com>
Implement custom O(1) header registration for header maps. - Remove virtual inheritence from header maps. - Implement variable inline storage for concrete header maps. - Various TODO/logic cleanups from previous header refactors. - Demonstrate what custom header registration looks like for the CORS filter. More cleanup of this type can be done. Signed-off-by: Matt Klein <mklein@lyft.com> Signed-off-by: yashwant121 <yadavyashwant36@gmail.com>
Test added by envoyproxy#11414 uses RequestHeaderMapImpl constructor made private in envoyproxy#11546 Signed-off-by: Florin Coras <fcoras@cisco.com> Signed-off-by: yashwant121 <yadavyashwant36@gmail.com>
Implement custom O(1) header registration for header maps.
CORS filter. More cleanup of this type can be done.
Fixes #4815
Risk Level: High
Testing: TBD
Docs Changes: N/A
Release Notes: N/A