neqo_glue::parse_headers spends a lot of time deserializing headers
Categories
(Core :: Networking: HTTP, defect, P2)
Tracking
()
| Tracking | Status | |
|---|---|---|
| firefox143 | --- | fixed |
People
(Reporter: valentin, Assigned: mail)
References
(Blocks 3 open bugs)
Details
(Whiteboard: [necko-triaged][necko-priority-queue])
Attachments
(2 files)
parse_headers currently takes 22% of the socket thread CPU in this profile https://share.firefox.dev/44zwMQF
This is entirely overhead. Instead of serializing the headers into mozilla::net::Http3Stream::mFlatHttpRequestHeaders and then splitting that string into an array of strings, mozilla::net::Http3Stream::GetHeadersString and mozilla::net::Http3WebTransportSession::ConsumeHeaders can dirrectly construct and append the Header::new object to the Vec<Header> and then pass that vec to the neqo_http3conn_fetch call.
| Reporter | ||
Updated•6 months ago
|
This should be a quick fix:
diff --git a/netwerk/socket/neqo_glue/src/lib.rs b/netwerk/socket/neqo_glue/src/lib.rs
index 21e82b920d9c..aaa19737afb3 100644
--- a/netwerk/socket/neqo_glue/src/lib.rs
+++ b/netwerk/socket/neqo_glue/src/lib.rs
@@ -958,13 +1078,13 @@ fn parse_headers(headers: &nsACString) -> Result<Vec<Header>, nsresult> {
if elem.is_empty() {
continue;
}
- let hdr_str: Vec<_> = elem.splitn(2, ':').collect();
- let name = hdr_str[0].trim().to_lowercase();
+ let mut hdr_str= elem.splitn(2, ':');
+ let name = hdr_str.next().unwrap().trim().to_lowercase();
if is_excluded_header(&name) {
continue;
}
- let value = if hdr_str.len() > 1 {
- String::from(hdr_str[1].trim())
+ let value = if let Some(value) = hdr_str.next(){
+ String::from(value.trim())
} else {
String::new()
};
| Reporter | ||
Comment 2•6 months ago
|
||
I'm OK with landing this fix today - nice improvement - but ultimately I'd like to avoid serializing into mFlatHttpRequestHeaders and instead just put Headers into the vec in Http3Stream::GetHeadersString .
Additional information:
Rust tests have one major restriction: they cannot link against Gecko symbols. Therefore, Rust tests cannot be used for crates that use Gecko crates like nsstring and xpcom.
https://firefox-source-docs.mozilla.org/testing-rust-code/#rust-tests
| Reporter | ||
Updated•5 months ago
|
Previously neqo_glue::parse_headers would allocate both header name
and header value twice while parsing. With this commit, both are
allocated only once.
Updated•5 months ago
|
Updated•5 months ago
|
Comment 7•3 months ago
|
||
| bugherder | ||
Comment 8•3 months ago
|
||
curious if there are any tests that would show improvements from this fix.
I am not aware of a micro benchmark that would be sensitive enough to detect the performance impact of https://phabricator.services.mozilla.com/D253684. Our assumption is, that removing two unnecessary allocations will always have a positive impact. Ideally we would have such a benchmark.
Updated•3 months ago
|
Description
•