Skip to content

Conversation

@taisho6339
Copy link

@taisho6339 taisho6339 commented Nov 29, 2025

Fixes #1125

Changes

Changed SpanProcessor::on_end() signature to accept &SpanData and &InstrumentationScope by reference. This eliminates unnecessary SpanData clones when multiple SpanProcessors are configured. Performance improvement scales with the number of processors. Processors that need to store the data asynchronously should clone it explicitly.

Merge requirement checklist

  • CONTRIBUTING guidelines followed
  • Unit tests added/updated (if applicable)
  • Appropriate CHANGELOG.md files updated for non-trivial, user-facing changes
  • Changes in public API reviewed (if applicable)

@taisho6339 taisho6339 changed the title refactor: avoid instrumentation_scope clone for every single span pro… refactor: avoid instrumentation_scope clone for every single span processor Nov 29, 2025
@codecov
Copy link

codecov bot commented Nov 29, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 80.8%. Comparing base (53c9f47) to head (2992427).

Additional details and impacted files
@@          Coverage Diff          @@
##            main   #3267   +/-   ##
=====================================
  Coverage   80.8%   80.8%           
=====================================
  Files        129     129           
  Lines      23203   23238   +35     
=====================================
+ Hits       18750   18793   +43     
+ Misses      4453    4445    -8     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@taisho6339 taisho6339 marked this pull request as ready for review November 29, 2025 03:21
@taisho6339 taisho6339 requested a review from a team as a code owner November 29, 2025 03:21
@lalitb
Copy link
Member

lalitb commented Dec 1, 2025

Thanks for the PR @taisho6339. Could you check if we can use a pattern similar to the one in the Logs SDK? In that implementation, the InstrumentationScope is passed by reference from the Logger to the Processor, allowing the Processor to decide whether to clone it or pass the reference to the exporter. I believe this approach was chosen to ensure the synchronous pipeline remains lightweight by avoiding cloning (even Arc overhead). This may lead to cloning of InstrumentationScope in case of batch processor, but that should also be cheap if the instrumentation-name is static string (which is the common use-case), and there are no attributes.

…nData` and `&InstrumentationScope` by reference

This eliminates unnecessary `SpanData` clones when multiple `SpanProcessor`s are configured. Performance improvement scales with the number of processors.
Processors that need to store the data asynchronously should clone it explicitly.
@taisho6339
Copy link
Author

taisho6339 commented Dec 1, 2025

@lalitb thank you for your feedback, that makes sense. I reflected it and I also changed SpanData to reference and pass it to SpanProcessors to align with the Log implementation.

@taisho6339 taisho6339 changed the title refactor: avoid instrumentation_scope clone for every single span processor refactor: avoid span_data and instrumentation_scope clone for every single span processor Dec 1, 2025
}
}
// Build export data once to avoid cloning for multiple processors
let export_data = build_export_data(data, self.span_context.clone(), &self.tracer);
Copy link
Member

Choose a reason for hiding this comment

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

build_export_data still clones the scope unnecessarily?

Copy link
Author

@taisho6339 taisho6339 Dec 1, 2025

Choose a reason for hiding this comment

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

Yes, build_export_data() still clones InstrumentationScope once, but this is a deliberate trade-off to maintain SpanData's public API compatibility. The real performance gain comes from eliminating (N-1) clones of the entire SpanData (~120+ bytes plus variable-length fields) in Span::end() when multiple processors are configured. Removing the instrumentation_scope field from SpanData or passing the reference entirely would be a larger breaking change that could be considered in a future PR.

Copy link
Member

Choose a reason for hiding this comment

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

We are okay to make breaking changes to Span/Tracing given its not marked stable. However, let's have a full analysis to this area before making the changes. There are few discussions in #2962 to be considered here.

(In general, yes, passing immutable ref to on_end makes total sense- just want to make sure we have the desired end state in mind before the implementation)

Copy link
Member

Choose a reason for hiding this comment

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

#2726 related issue.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, please take a look at #2962 @taisho6339 and come with input there.

@taisho6339 taisho6339 requested a review from cijothomas December 1, 2025 23:48
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.

Performance: send instrumentation library data to span processors once, not for every span when it ends

4 participants