perf: avoid allocating a mapping lambda on every labelValues() call - #2442
Open
david-mollitor-db wants to merge 1 commit into
Open
perf: avoid allocating a mapping lambda on every labelValues() call#2442david-mollitor-db wants to merge 1 commit into
david-mollitor-db wants to merge 1 commit into
Conversation
labelValues() went straight to data.computeIfAbsent(key, l -> ...). The mapping function captures 'this', so a new lambda instance was allocated on every call - including the common case where the data point already exists, since the lambda argument is constructed before computeIfAbsent runs. Add a data.get(key) fast path that returns the existing data point without constructing the lambda. In a JMH benchmark of a histogram-heavy workload this cut record-path allocation by ~18% (exactly the 16-byte captured lambda per observation). On the miss path, validate the label values on the raw array before computeIfAbsent, so the null check runs outside the ConcurrentHashMap bin lock and without List indirection. Creation stays inside computeIfAbsent: newDataPoint() has side effects (a native histogram may schedule a reset task), so at-most-once creation must be preserved. Behavior is unchanged (verified by the core tests, including StatefulMetricTest). Signed-off-by: David Mollitor <david.mollitor@databricks.com>
david-mollitor-db
requested review from
dhoard,
fstab,
jaydeluca and
zeitlinger
as code owners
September 1, 2026 19:57
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.
What
StatefulMetric.labelValues(...)— the path everycounter.labelValues(...).inc()/histogram.labelValues(...).observe(...)goes through — calleddata.computeIfAbsent(key, l -> newDataPoint())on every invocation. The mapping functioncaptures
this(viametadata/labelNames), so it is not a cached singleton: a new lambdainstance is allocated on every call, including the overwhelmingly common case where the data point
already exists (the lambda argument is constructed before
computeIfAbsentruns, even though it isonly invoked on a miss).
This adds a
data.get(key)fast path that returns the existing data point without constructing thelambda:
Two secondary points folded in on the miss path:
computeIfAbsent, i.e. outside theConcurrentHashMapbin lock, and operates on the rawString[](noList.getindirection);computeIfAbsenton purpose —newDataPoint()has a side effect (a nativehistogram may schedule a reset task via
Scheduler.schedule), so at-most-once creation must bepreserved;
putIfAbsentwith a pre-built value would leak the loser's scheduled task on a race.Why
labelValues(...)is the hottest path in the library (every metric update). In a JMH benchmark of ahistogram-heavy workload, the
get()fast path cut record-path allocation by ~18% — exactly the16-byte captured lambda per observation.
Correctness
Behavior is unchanged (a null label value still throws on first use, since a null-containing key is
never inserted and so always reaches the miss branch). Verified by the core tests, including
StatefulMetricTest.This pull request and its description were written by Isaac.