perf(mapping): reduce allocations in unmarshal hot path#5606
Open
yaoyi1222 wants to merge 1 commit into
Open
Conversation
Two behavior-preserving changes that cut allocations on the config-load
and per-request request-parsing paths.
getValue: the form/path unmarshalers in rest/httpx use WithOpaqueKeys,
and opaque keys are never split on the delimiter, so they always resolve
to a single lookup. readKeys allocates a one-element []string{key} for
each such key, which getValueWithChainedKeys then reduces to a single
Valuer.Value call. Call Value directly and skip the slice allocation.
join: fullName is only used to build error messages, yet join() runs a
strings.Builder (and an allocating String() copy) for every named field.
When at most one segment is non-empty (top-level fields, where the parent
name is empty) return it directly. Error messages are byte-identical.
benchstat (Apple M1 Pro, count=8, all p<0.05):
rest/httpx ParseAuto: 30->24 allocs/op (-20%), -7.4% time
mapping Unmarshal: 8->5 allocs/op (-37%), -8.3% time
mapping UnmarshalString: 4->3 allocs/op (-25%), -7.5% time
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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.
Two small, behavior-preserving changes that cut allocations on the config-load and per-request request-parsing paths.
getValueThe form/path unmarshalers in
rest/httpxuseWithOpaqueKeys, and opaque keys are never split on the delimiter, so they always resolve to a single lookup.readKeysallocates a one-element[]string{key}for each such key, whichgetValueWithChainedKeysthen collapses to a singleValuer.Valuecall. CallValuedirectly and skip the slice allocation. This is on the per-request hot path.joinfullNameis only used to build error messages, yetjoin()runs astrings.Builder(and an allocatingString()copy) for every named field. When at most one segment is non-empty (top-level fields, where the parent name is empty) return it directly. Error messages are byte-identical.Benchmarks
benchstat, Apple M1 Pro,
-count=8, allp<0.05:Both paths are exercised on every service start (config loading) and every HTTP request (
httpx.Parse).Notes
getValueWithChainedKeys.go test ./core/mapping/... ./core/conf/... ./rest/...passes;go vetclean.