perf(http): single Map probe in read_headers via update_or_default#390
Open
mizchi wants to merge 1 commit into
Open
perf(http): single Map probe in read_headers via update_or_default#390mizchi wants to merge 1 commit into
mizchi wants to merge 1 commit into
Conversation
Reader::read_headers did two Map operations per header:
match headers.get(key) {
None => headers[key] = value
Some(value0) => headers[key] = "\\{value0},\\{value}"
}
Map::get walks the Robin-Hood probe sequence once; the subsequent
headers[key] = ... walks it again. Map::update_or_default already
exists for this pattern and does a single probe.
Semantically identical (HTTP requires comma-joining duplicate header
names). Wall-time delta is within noise on GET / -- visible work is
dominated by moonbit_drop_object + malloc -- but the refactor costs
nothing and is arguably clearer.
Guest0x0
reviewed
May 29, 2026
Guest0x0
left a comment
Collaborator
There was a problem hiding this comment.
lgtm except the minor comment issue
| Some(value0) => headers[key] = "\{value0},\{value}" | ||
| } | ||
| // Single hashmap probe (was 2: get + set). For repeated header | ||
| // names HTTP requires comma-joining; for new keys we just insert. |
Collaborator
There was a problem hiding this comment.
the comment feels unnecessary here
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Reader::read_headersinsrc/http/parser.mbtdoes twoMapoperations per header:Map::getwalks the Robin-Hood probe sequence once; the subsequentheaders[key] = ...walks it again from scratch.Map::update_or_default(key, default, update_fn)already exists for exactly this pattern and does a single probe.headers.update_or_default(key, value, value0 => "\{value0},\{value}")Why bother
Headers are parsed for every HTTP request. The save is small per call (one extra hash + one probe walk) but compounds across the request lifetime — and the new version is semantically identical and arguably clearer.
Scenario:
bench-async/cmd/http_server_benchmark/main.mbt— the example HTTP server driven by k6 (3,330 req/s under valgrind, 67 kreq/s native). In the callgrind profileread_headersitself is 2.40% of instructions and the Map insert path inside it is a slice of that. Wall-time delta is within the run-to-run noise (~±2%) on aGET /workload — the visible work is dominated bymoonbit_drop_object+ malloc — but the patch costs nothing.Test results
Network round-trip tests (real socket / tls / http) require a network interface this sandbox lacks; this patch does not touch any code on that path.