Skip to content

[OpenTelemetry] Avoid enumerator allocations - #7681

Merged
martincostello merged 2 commits into
open-telemetry:mainfrom
martincostello:avoid-enumerator-allocations
Sep 1, 2026
Merged

martincostello merged 2 commits into
open-telemetry:mainfrom
martincostello:avoid-enumerator-allocations

Conversation

@martincostello

Copy link
Copy Markdown
Member

Changes

  • Avoid allocating array when enumerating log scopes.
  • Avoid allocating enumerator when sampling attributes are a list.

Found by investigating profile allocations in an application after upgrading to 1.18.0.

SamplingResultBenchmarks:

Method Before (Allocated) After (Allocated) Difference % Reduction
NoAttributes 328 B 328 B 0 B 0%
WithAttributeArray 672 B 640 B -32 B 4.8%
WithAttributeList 752 B 720 B -32 B 4.3%
Drop 328 B 328 B 0 B 0%
ParentBasedSampled 328 B 328 B 0 B 0%

Scope Benchmarks

Benchmark Before Mean After Mean Delta Mean Before Alloc After Alloc
ForEachScope 35.84 ns 27.16 ns -24% 144 B 56 B
Scope Benchmarks
using BenchmarkDotNet.Attributes;
using Microsoft.Extensions.Logging;
using OpenTelemetry.Logs;

namespace Benchmarks.Logs;

[MemoryDiagnoser]
public class LogScopeDictionaryBenchmarks
{
    private readonly LoggerExternalScopeProvider scopeProvider = new();

    private readonly Action<LogRecordScope, object> callback = (scope, state) =>
    {
        foreach (var scopeItem in scope)
        {
            _ = scopeItem.Key;
            _ = scopeItem.Value;
        }
    };

    private readonly LogRecord logRecord;

    public LogScopeDictionaryBenchmarks()
    {
        this.scopeProvider.Push(new Dictionary<string, object>
        {
            ["RequestId"] = "abc123",
            ["UserId"] = 42,
            ["TenantId"] = Guid.NewGuid(),
            ["StartedAt"] = DateTime.UtcNow,
        });

        this.logRecord = new LogRecord(
            this.scopeProvider,
            DateTime.UtcNow,
            "Benchmark",
            LogLevel.Information,
            0,
            "Message",
            null,
            null,
            null);
    }

    [Benchmark]
    public void ForEachScope()
    {
        this.logRecord.ForEachScope(this.callback!, null);
    }
}

Merge requirement checklist

  • CONTRIBUTING guidelines followed (license requirements, nullable enabled, static analysis, etc.)
  • Unit tests added/updated
  • Appropriate CHANGELOG.md files updated for non-trivial changes
  • Changes in public API reviewed (if applicable)

- Avoid allocating array when enumerating log scopes.
- Avoid allocating enumerator when sampling attributes are a list.
@github-actions github-actions Bot added the pkg:OpenTelemetry Issues related to OpenTelemetry NuGet package label Aug 22, 2026
@martincostello
martincostello requested a balanced review from Copilot August 22, 2026 12:27
@codecov

codecov Bot commented Aug 22, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.48%. Comparing base (63d9cd1) to head (7094a07).
⚠️ Report is 21 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #7681      +/-   ##
==========================================
+ Coverage   91.45%   91.48%   +0.02%     
==========================================
  Files         318      318              
  Lines       17867    17881      +14     
==========================================
+ Hits        16341    16358      +17     
+ Misses       1526     1523       -3     
Flag Coverage Δ
unittests-Project-Experimental 91.57% <100.00%> (-0.01%) ⬇️
unittests-Project-Stable 91.55% <100.00%> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/OpenTelemetry/Logs/LogRecordScope.cs 92.30% <100.00%> (+3.41%) ⬆️
src/OpenTelemetry/Trace/TracerProviderSdk.cs 97.36% <100.00%> (+0.04%) ⬆️

... and 1 file with indirect coverage changes

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

Optimizes hot-path enumeration in tracing and logging to reduce allocations.

Changes:

  • Indexes sampling attribute lists without allocating enumerators.
  • Streams non-list log scopes instead of materializing arrays.

Reviewed changes

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

File Description
src/OpenTelemetry/Trace/TracerProviderSdk.cs Adds list-aware sampling attribute iteration.
src/OpenTelemetry/Logs/LogRecordScope.cs Delegates enumeration for non-list scopes.

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

Comment thread src/OpenTelemetry/Trace/TracerProviderSdk.cs Outdated
Comment thread src/OpenTelemetry/Trace/TracerProviderSdk.cs Outdated
Comment thread src/OpenTelemetry/Logs/LogRecordScope.cs
- Apply the optimisation to both enumeration sites.
- Extend test coverage.
@martincostello
martincostello marked this pull request as ready for review August 22, 2026 13:16
@martincostello
martincostello requested a review from a team as a code owner August 22, 2026 13:16
@opentelemetry-pr-dashboard

opentelemetry-pr-dashboard Bot commented Aug 22, 2026 •

Copy link
Copy Markdown

Pull request dashboard status

Merged · refreshed 2026-09-01 08:17 UTC

Status above doesn't look right?
  • Anything look wrong? Report it with what you expected; it helps us improve the dashboard.

@martincostello martincostello added the keep-open Prevents issues and pull requests being closed as stale label Aug 29, 2026
@martincostello
martincostello added this pull request to the merge queue Sep 1, 2026
Merged via the queue into open-telemetry:main with commit 5c11a86 Sep 1, 2026
80 checks passed
@martincostello
martincostello deleted the avoid-enumerator-allocations branch September 1, 2026 08:04
@martincostello martincostello added this to the v1.19.0 milestone Sep 14, 2026
@martincostello martincostello removed the keep-open Prevents issues and pull requests being closed as stale label Sep 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pkg:OpenTelemetry Issues related to OpenTelemetry NuGet package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants