Skip to content

expfmt: precompute parsed goautoneg.Accept for well-known Format constants - #967

Merged
bwplotka merged 1 commit into
prometheus:mainfrom
dashpole:perf-negotiate-accept-preparse
Aug 24, 2026
Merged

expfmt: precompute parsed goautoneg.Accept for well-known Format constants#967
bwplotka merged 1 commit into
prometheus:mainfrom
dashpole:perf-negotiate-accept-preparse

Conversation

@dashpole

@dashpole dashpole commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Fixes a small performance regression introduced by #894.

Repeatedly parsing static Format constants with goautoneg.ParseAccept in matchFormat on every call causes heap allocations during negotiation.

Precompute the parsed goautoneg.Accept structs for standard Format constants at package initialization time, falling back to goautoneg.ParseAccept for custom formats. Also add benchmarks with b.ReportAllocs() to track negotiation performance.

goos: linux
goarch: amd64
pkg: github.com/prometheus/common/expfmt
cpu: AMD EPYC 7B12
                                 │ /tmp/before.txt │           /tmp/after.txt            │
                                 │     sec/op      │   sec/op     vs base                │
Negotiate-24                         3.074µ ±   6%   2.240µ ± 2%  -27.10% (p=0.000 n=10)
NegotiateIncludingOpenMetrics-24     3.180µ ±   3%   2.314µ ± 2%  -27.22% (p=0.000 n=10)
NegotiateAccept-24                   3.138µ ± 153%   1.768µ ± 4%  -43.67% (p=0.000 n=10)
geomean                              3.130µ          2.093µ       -33.14%

                                 │ /tmp/before.txt │            /tmp/after.txt            │
                                 │      B/op       │     B/op      vs base                │
Negotiate-24                          1.524Ki ± 0%   1.086Ki ± 0%  -28.76% (p=0.000 n=10)
NegotiateIncludingOpenMetrics-24      1.759Ki ± 0%   1.320Ki ± 0%  -24.93% (p=0.000 n=10)
NegotiateAccept-24                     1417.0 ± 0%     968.0 ± 0%  -31.69% (p=0.000 n=10)
geomean                               1.548Ki        1.107Ki       -28.51%

                                 │ /tmp/before.txt │           /tmp/after.txt           │
                                 │    allocs/op    │ allocs/op   vs base                │
Negotiate-24                           15.000 ± 0%   9.000 ± 0%  -40.00% (p=0.000 n=10)
NegotiateIncludingOpenMetrics-24        16.00 ± 0%   10.00 ± 0%  -37.50% (p=0.000 n=10)
NegotiateAccept-24                     14.000 ± 0%   8.000 ± 0%  -42.86% (p=0.000 n=10)
geomean                                 14.98        8.963       -40.16%

…tants

Repeatedly parsing static Format constants with goautoneg.ParseAccept in
matchFormat on every call causes unnecessary heap allocations and latency
during content negotiation.

Precompute the parsed goautoneg.Accept structs for standard Format
constants at package initialization time, falling back to goautoneg.ParseAccept
for custom formats. Also add benchmarks with b.ReportAllocs() to track
negotiation performance.

Signed-off-by: David Ashpole <dashpole@google.com>
@dashpole
dashpole force-pushed the perf-negotiate-accept-preparse branch from 7138172 to edc2a8e Compare August 24, 2026 15:57
@dashpole
dashpole requested a lite review from Copilot August 24, 2026 16:00

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses a performance regression in expfmt content-type negotiation by avoiding repeated parsing of static Format constants with goautoneg.ParseAccept, reducing allocations and improving negotiation throughput.

Changes:

  • Precompute parsed goautoneg.Accept values for well-known Format constants at package initialization, with a fallback parse for custom formats.
  • Simplify escaping parameter construction in NegotiateAccept to avoid unnecessary formatting overhead.
  • Add benchmarks (with allocation reporting) to track negotiation performance and catch regressions.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
expfmt/encode.go Adds a precomputed FormatAccept lookup to avoid per-call parsing in matchFormat, and simplifies escaping suffix construction.
expfmt/encode_test.go Adds benchmarks for negotiation paths and reports allocations to guard against future regressions.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@dashpole
dashpole requested a review from bwplotka August 24, 2026 16:23
@dashpole
dashpole marked this pull request as ready for review August 24, 2026 16:23
@dashpole
dashpole requested a review from krajorama August 24, 2026 16:24

@bwplotka bwplotka left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks

@bwplotka
bwplotka merged commit 87e7482 into prometheus:main Aug 24, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants