[OpenTelemetry] Use AlternateLookup#7467
Conversation
Optimize metrics tag using alternate lookup when targeting .NET 9+. Contributes to open-telemetry#5777.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #7467 +/- ##
==========================================
+ Coverage 90.05% 90.06% +0.01%
==========================================
Files 284 285 +1
Lines 15230 15256 +26
==========================================
+ Hits 13716 13741 +25
- Misses 1514 1515 +1
Flags with carried forward coverage won't be shown. Click here to find out more.
|
Add an alternate lookup-based fast path for delta temporality.
There was a problem hiding this comment.
Pull request overview
This PR optimizes the metrics tag-set lookup hot path for .NET 9+ by using ConcurrentDictionary.GetAlternateLookup to probe the existing time-series map directly from the incoming ReadOnlySpan<KeyValuePair<string, object?>>, avoiding the thread-static copy on lookup hits.
Changes:
- Add
TagsComparerimplementingIAlternateEqualityComparer(NET9+) to enable span-based alternate lookups forTagskeys. - Extend
Tagswith span-based equality and span-based hash code computation to ensure alternate lookups are correct and consistent withTagsinstances. - Use alternate lookup fast paths in
AggregatorStore(both cumulative and delta-with-reclaim hit paths) and add unit tests covering the new comparer/hash semantics.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| test/OpenTelemetry.Tests/Metrics/TagsTests.cs | Adds tests for span-based Tags.Equals and span hash parity with instance hash. |
| test/OpenTelemetry.Tests/Metrics/TagsComparerTests.cs | Adds NET9+ tests validating TagsComparer alternate hash/equals and an end-to-end ConcurrentDictionary alternate lookup hit. |
| src/OpenTelemetry/Metrics/TagsComparer.cs | Introduces a singleton comparer enabling NET9+ alternate lookup from a tags span to Tags. |
| src/OpenTelemetry/Metrics/Tags.cs | Adds span-based equality and ComputeHashCode(ReadOnlySpan<...>) to support alternate lookups. |
| src/OpenTelemetry/Metrics/AggregatorStore.cs | Wires in TagsComparer and uses alternate lookups for NET9+ lookup-hit paths (cumulative and delta-with-reclaim). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Fixes #5777
Changes
Optimize metrics tag using alternate lookup when targeting .NET 9+.
Benchmarks
I got Claude to write a throwaway benchmark (I don't think it's worth committing as it's very focussed on this exact change). Claude's summary plus the benchmark's code are below.
Summary
Avoids copying the incoming tags
ReadOnlySpaninto thread-static storage on the metrics hot path by looking the metric point up directly from the span viaConcurrentDictionary.GetAlternateLookup(net9.0+). Applies to both cumulative and the delta-with-reclaim lookup paths.Benchmark: branch vs
mainbaseline (net10.0)MetricsLookupBenchmarks.CounterHotPathExistingSeries— recording into an already-existing time series (the steady-state lookup-hit path). Both runs executed on the same machine, sequentially, default job,MemoryDiagnoserenabled.Allocated:
-(zero) on both sides in every case — the optimization is pure CPU; the hit path was already allocation-free (thread-static reuse), so this removes the per-tag array copy, not allocations.Takeaways
Tagsand resolvesLookupData, so skipping the copy is proportionally bigger; absolute savings reach −60 ns at 7 tags.SplitToKeysAndValues).Notes
Code
Expand to view
Merge requirement checklist
AppropriateCHANGELOG.mdfiles updated for non-trivial changesChanges in public API reviewed (if applicable)