-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Optimizing the trace sdk #6721
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Any improvement is welcome. But each separate improvement should be its own PR with benchmark comparison (either using the existing benchmarks, or adding new ones). |
Instead of using a mutex, use atomic compare-and-swap to set the endTime. Store unix nanoseconds as an int64 to enable atomics. This has few nice properties: - Span.End() no longer needs the mutex. The first call to Span.End() does an atomic compare-and-swap. Later calls will return early. - We remove the isRecording method and use the public IsRecording method since we don't need the mutex to access endTime. - We reduce the recordingSpan size by 32 bytes. time.Time takes 24 bytes compared to 8 bytes for int64 nanoseconds. We save 16 bytes each for startTime and endTime. Benchstat ``` benchstat private/base2.txt private/new2.txt goos: darwin goarch: arm64 pkg: go.opentelemetry.io/otel/sdk/trace cpu: Apple M2 Max │ private/base2.txt │ private/new2.txt │ │ sec/op │ sec/op vs base │ Truncate/Unlimited-12 0.2089n ± 2% 0.2090n ± 4% ~ (p=0.698 n=10) Truncate/Zero-12 0.3052n ± 1% 0.3087n ± 20% ~ (p=0.127 n=10) Truncate/Short-12 0.2081n ± 0% 0.2089n ± 1% ~ (p=0.362 n=10) Truncate/ASCII-12 0.7140n ± 2% 0.6855n ± 0% -4.00% (p=0.000 n=10) Truncate/ValidUTF-8-12 1.311n ± 2% 1.303n ± 1% -0.61% (p=0.015 n=10) Truncate/InvalidUTF-8-12 9.437n ± 1% 9.315n ± 3% ~ (p=0.143 n=10) Truncate/MixedUTF-8-12 17.32n ± 0% 17.16n ± 2% ~ (p=0.159 n=10) RecordingSpanSetAttributes/WithLimit/false-12 2.080µ ± 1% 2.010µ ± 1% -3.39% (p=0.000 n=10) RecordingSpanSetAttributes/WithLimit/true-12 4.358µ ± 0% 4.297µ ± 0% -1.40% (p=0.000 n=10) SpanEnd-12 107.90n ± 10% 94.44n ± 1% -12.47% (p=0.001 n=10) TraceStart/with_a_simple_span-12 319.5n ± 6% 293.7n ± 3% -8.08% (p=0.000 n=10) TraceStart/with_several_links-12 428.3n ± 2% 411.2n ± 1% -3.99% (p=0.000 n=10) TraceStart/with_attributes-12 469.6n ± 3% 430.4n ± 1% -8.35% (p=0.000 n=10) SpanLimits/AttributeValueLengthLimit-12 4.379µ ± 1% 4.144µ ± 1% -5.38% (p=0.000 n=10) SpanLimits/AttributeCountLimit-12 4.219µ ± 2% 3.909µ ± 1% -7.36% (p=0.000 n=10) SpanLimits/EventCountLimit-12 3.994µ ± 6% 3.663µ ± 1% -8.28% (p=0.000 n=10) SpanLimits/LinkCountLimit-12 3.835µ ± 2% 3.619µ ± 1% -5.63% (p=0.000 n=10) SpanLimits/AttributePerEventCountLimit-12 4.225µ ± 3% 3.961µ ± 1% -6.25% (p=0.000 n=10) SpanLimits/AttributePerLinkCountLimit-12 4.218µ ± 1% 3.951µ ± 1% -6.32% (p=0.000 n=10) SpanSetAttributesOverCapacity-12 1.676µ ± 2% 1.582µ ± 0% -5.58% (p=0.000 n=10) StartEndSpan/AlwaysSample-12 322.3n ± 0% 279.1n ± 0% -13.40% (p=0.000 n=10) StartEndSpan/NeverSample-12 153.5n ± 4% 148.1n ± 0% -3.55% (p=0.000 n=10) SpanWithAttributes_4/AlwaysSample-12 527.6n ± 1% 467.7n ± 0% -11.36% (p=0.000 n=10) SpanWithAttributes_4/NeverSample-12 245.1n ± 0% 227.6n ± 0% -7.14% (p=0.000 n=10) SpanWithAttributes_8/AlwaysSample-12 702.7n ± 2% 638.2n ± 1% -9.19% (p=0.000 n=10) SpanWithAttributes_8/NeverSample-12 336.4n ± 1% 305.0n ± 1% -9.32% (p=0.000 n=10) SpanWithAttributes_all/AlwaysSample-12 593.9n ± 3% 518.8n ± 1% -12.65% (p=0.000 n=10) SpanWithAttributes_all/NeverSample-12 267.0n ± 3% 251.6n ± 0% -5.73% (p=0.000 n=10) SpanWithAttributes_all_2x/AlwaysSample-12 850.2n ± 1% 749.9n ± 0% -11.80% (p=0.000 n=10) SpanWithAttributes_all_2x/NeverSample-12 398.4n ± 2% 350.8n ± 2% -11.95% (p=0.000 n=10) SpanWithEvents_4/AlwaysSample-12 736.3n ± 9% 640.9n ± 0% -12.96% (p=0.000 n=10) SpanWithEvents_4/NeverSample-12 158.1n ± 3% 149.8n ± 0% -5.25% (p=0.000 n=10) SpanWithEvents_8/AlwaysSample-12 1111.5n ± 1% 995.0n ± 0% -10.48% (p=0.000 n=10) SpanWithEvents_8/NeverSample-12 159.9n ± 2% 153.1n ± 0% -4.28% (p=0.000 n=10) SpanWithEvents_WithStackTrace/AlwaysSample-12 446.3n ± 1% 395.8n ± 0% -11.30% (p=0.000 n=10) SpanWithEvents_WithStackTrace/NeverSample-12 170.4n ± 1% 161.4n ± 0% -5.25% (p=0.000 n=10) SpanWithEvents_WithTimestamp/AlwaysSample-12 441.9n ± 1% 379.1n ± 0% -14.19% (p=0.000 n=10) SpanWithEvents_WithTimestamp/NeverSample-12 196.3n ± 5% 185.2n ± 1% -5.65% (p=0.000 n=10) TraceID_DotString-12 43.07n ± 1% 40.19n ± 0% -6.69% (p=0.000 n=10) SpanID_DotString-12 31.61n ± 1% 32.63n ± 0% +3.23% (p=0.001 n=10) SpanProcessorOnEnd/batch:_10,_spans:_10-12 163.3n ± 3% 162.3n ± 0% -0.64% (p=0.010 n=10) SpanProcessorOnEnd/batch:_10,_spans:_100-12 1.645µ ± 1% 1.624µ ± 0% -1.31% (p=0.000 n=10) SpanProcessorOnEnd/batch:_100,_spans:_10-12 162.2n ± 1% 162.5n ± 0% ~ (p=0.587 n=10) SpanProcessorOnEnd/batch:_100,_spans:_100-12 1.626µ ± 1% 1.623µ ± 0% ~ (p=0.361 n=10) SpanProcessorVerboseLogging-12 6.795µ ± 2% 5.789µ ± 3% -14.81% (p=0.000 n=10) geomean 225.5n 211.6n -6.19% │ private/base2.txt │ private/new2.txt │ │ B/op │ B/op vs base │ Truncate/Unlimited-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Zero-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Short-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ASCII-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ValidUTF-8-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/InvalidUTF-8-12 16.00 ± 0% 16.00 ± 0% ~ (p=1.000 n=10) ¹ Truncate/MixedUTF-8-12 32.00 ± 0% 32.00 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/false-12 6.891Ki ± 0% 6.859Ki ± 0% -0.45% (p=0.000 n=10) RecordingSpanSetAttributes/WithLimit/true-12 7.023Ki ± 0% 6.992Ki ± 0% -0.44% (p=0.000 n=10) SpanEnd-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_a_simple_span-12 528.0 ± 0% 496.0 ± 0% -6.06% (p=0.000 n=10) TraceStart/with_several_links-12 704.0 ± 0% 672.0 ± 0% -4.55% (p=0.000 n=10) TraceStart/with_attributes-12 784.0 ± 0% 752.0 ± 0% -4.08% (p=0.000 n=10) SpanLimits/AttributeValueLengthLimit-12 10.56Ki ± 0% 10.53Ki ± 0% -0.30% (p=0.000 n=10) SpanLimits/AttributeCountLimit-12 9.844Ki ± 0% 9.812Ki ± 0% -0.32% (p=0.000 n=10) SpanLimits/EventCountLimit-12 9.422Ki ± 0% 9.391Ki ± 0% -0.33% (p=0.000 n=10) SpanLimits/LinkCountLimit-12 9.031Ki ± 0% 9.000Ki ± 0% -0.35% (p=0.000 n=10) SpanLimits/AttributePerEventCountLimit-12 10.47Ki ± 0% 10.44Ki ± 0% -0.30% (p=0.000 n=10) SpanLimits/AttributePerLinkCountLimit-12 10.47Ki ± 0% 10.44Ki ± 0% -0.30% (p=0.000 n=10) SpanSetAttributesOverCapacity-12 592.0 ± 0% 560.0 ± 0% -5.41% (p=0.000 n=10) StartEndSpan/AlwaysSample-12 528.0 ± 0% 496.0 ± 0% -6.06% (p=0.000 n=10) StartEndSpan/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/AlwaysSample-12 1040.0 ± 0% 1008.0 ± 0% -3.08% (p=0.000 n=10) SpanWithAttributes_4/NeverSample-12 400.0 ± 0% 400.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/AlwaysSample-12 1.516Ki ± 0% 1.484Ki ± 0% -2.06% (p=0.000 n=10) SpanWithAttributes_8/NeverSample-12 656.0 ± 0% 656.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/AlwaysSample-12 1.141Ki ± 0% 1.109Ki ± 0% -2.74% (p=0.000 n=10) SpanWithAttributes_all/NeverSample-12 464.0 ± 0% 464.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/AlwaysSample-12 1.891Ki ± 0% 1.859Ki ± 0% -1.65% (p=0.000 n=10) SpanWithAttributes_all_2x/NeverSample-12 848.0 ± 0% 848.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/AlwaysSample-12 1040.0 ± 0% 1008.0 ± 0% -3.08% (p=0.000 n=10) SpanWithEvents_4/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/AlwaysSample-12 1.641Ki ± 0% 1.609Ki ± 0% -1.90% (p=0.000 n=10) SpanWithEvents_8/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/AlwaysSample-12 624.0 ± 0% 592.0 ± 0% -5.13% (p=0.000 n=10) SpanWithEvents_WithStackTrace/NeverSample-12 160.0 ± 0% 160.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/AlwaysSample-12 648.0 ± 0% 616.0 ± 0% -4.94% (p=0.000 n=10) SpanWithEvents_WithTimestamp/NeverSample-12 184.0 ± 0% 184.0 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorVerboseLogging-12 9.547Ki ± 0% 9.234Ki ± 0% -3.27% (p=0.000 n=10) geomean ² -1.34% ² ¹ all samples are equal ² summaries must be >0 to compute geomean │ private/base2.txt │ private/new2.txt │ │ allocs/op │ allocs/op vs base │ Truncate/Unlimited-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Zero-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Short-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ASCII-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ValidUTF-8-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/InvalidUTF-8-12 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/MixedUTF-8-12 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/false-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/true-12 10.00 ± 0% 10.00 ± 0% ~ (p=1.000 n=10) ¹ SpanEnd-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_a_simple_span-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_several_links-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_attributes-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributeValueLengthLimit-12 41.00 ± 0% 41.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributeCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/EventCountLimit-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/LinkCountLimit-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributePerEventCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributePerLinkCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanSetAttributesOverCapacity-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ StartEndSpan/AlwaysSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ StartEndSpan/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/AlwaysSample-12 5.000 ± 0% 5.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/AlwaysSample-12 6.000 ± 0% 6.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/AlwaysSample-12 5.000 ± 0% 5.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/NeverSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorVerboseLogging-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ geomean ² +0.00% ² ¹ all samples are equal ² summaries must be >0 to compute geomean See open-telemetry#6721.
Instead of using a mutex, use atomic compare-and-swap to set the endTime. Store unix nanoseconds as an int64 to enable atomics. This has few nice properties: - Span.End() no longer needs the mutex. The first call to Span.End() does an atomic compare-and-swap. Later calls will return early. - We remove the isRecording method and use the public IsRecording method since we don't need the mutex to access endTime. - We reduce the recordingSpan size by 32 bytes. time.Time takes 24 bytes compared to 8 bytes for int64 nanoseconds. We save 16 bytes each for startTime and endTime. Benchstat ``` benchstat private/base2.txt private/new2.txt goos: darwin goarch: arm64 pkg: go.opentelemetry.io/otel/sdk/trace cpu: Apple M2 Max │ private/base2.txt │ private/new2.txt │ │ sec/op │ sec/op vs base │ Truncate/Unlimited-12 0.2089n ± 2% 0.2090n ± 4% ~ (p=0.698 n=10) Truncate/Zero-12 0.3052n ± 1% 0.3087n ± 20% ~ (p=0.127 n=10) Truncate/Short-12 0.2081n ± 0% 0.2089n ± 1% ~ (p=0.362 n=10) Truncate/ASCII-12 0.7140n ± 2% 0.6855n ± 0% -4.00% (p=0.000 n=10) Truncate/ValidUTF-8-12 1.311n ± 2% 1.303n ± 1% -0.61% (p=0.015 n=10) Truncate/InvalidUTF-8-12 9.437n ± 1% 9.315n ± 3% ~ (p=0.143 n=10) Truncate/MixedUTF-8-12 17.32n ± 0% 17.16n ± 2% ~ (p=0.159 n=10) RecordingSpanSetAttributes/WithLimit/false-12 2.080µ ± 1% 2.010µ ± 1% -3.39% (p=0.000 n=10) RecordingSpanSetAttributes/WithLimit/true-12 4.358µ ± 0% 4.297µ ± 0% -1.40% (p=0.000 n=10) SpanEnd-12 107.90n ± 10% 94.44n ± 1% -12.47% (p=0.001 n=10) TraceStart/with_a_simple_span-12 319.5n ± 6% 293.7n ± 3% -8.08% (p=0.000 n=10) TraceStart/with_several_links-12 428.3n ± 2% 411.2n ± 1% -3.99% (p=0.000 n=10) TraceStart/with_attributes-12 469.6n ± 3% 430.4n ± 1% -8.35% (p=0.000 n=10) SpanLimits/AttributeValueLengthLimit-12 4.379µ ± 1% 4.144µ ± 1% -5.38% (p=0.000 n=10) SpanLimits/AttributeCountLimit-12 4.219µ ± 2% 3.909µ ± 1% -7.36% (p=0.000 n=10) SpanLimits/EventCountLimit-12 3.994µ ± 6% 3.663µ ± 1% -8.28% (p=0.000 n=10) SpanLimits/LinkCountLimit-12 3.835µ ± 2% 3.619µ ± 1% -5.63% (p=0.000 n=10) SpanLimits/AttributePerEventCountLimit-12 4.225µ ± 3% 3.961µ ± 1% -6.25% (p=0.000 n=10) SpanLimits/AttributePerLinkCountLimit-12 4.218µ ± 1% 3.951µ ± 1% -6.32% (p=0.000 n=10) SpanSetAttributesOverCapacity-12 1.676µ ± 2% 1.582µ ± 0% -5.58% (p=0.000 n=10) StartEndSpan/AlwaysSample-12 322.3n ± 0% 279.1n ± 0% -13.40% (p=0.000 n=10) StartEndSpan/NeverSample-12 153.5n ± 4% 148.1n ± 0% -3.55% (p=0.000 n=10) SpanWithAttributes_4/AlwaysSample-12 527.6n ± 1% 467.7n ± 0% -11.36% (p=0.000 n=10) SpanWithAttributes_4/NeverSample-12 245.1n ± 0% 227.6n ± 0% -7.14% (p=0.000 n=10) SpanWithAttributes_8/AlwaysSample-12 702.7n ± 2% 638.2n ± 1% -9.19% (p=0.000 n=10) SpanWithAttributes_8/NeverSample-12 336.4n ± 1% 305.0n ± 1% -9.32% (p=0.000 n=10) SpanWithAttributes_all/AlwaysSample-12 593.9n ± 3% 518.8n ± 1% -12.65% (p=0.000 n=10) SpanWithAttributes_all/NeverSample-12 267.0n ± 3% 251.6n ± 0% -5.73% (p=0.000 n=10) SpanWithAttributes_all_2x/AlwaysSample-12 850.2n ± 1% 749.9n ± 0% -11.80% (p=0.000 n=10) SpanWithAttributes_all_2x/NeverSample-12 398.4n ± 2% 350.8n ± 2% -11.95% (p=0.000 n=10) SpanWithEvents_4/AlwaysSample-12 736.3n ± 9% 640.9n ± 0% -12.96% (p=0.000 n=10) SpanWithEvents_4/NeverSample-12 158.1n ± 3% 149.8n ± 0% -5.25% (p=0.000 n=10) SpanWithEvents_8/AlwaysSample-12 1111.5n ± 1% 995.0n ± 0% -10.48% (p=0.000 n=10) SpanWithEvents_8/NeverSample-12 159.9n ± 2% 153.1n ± 0% -4.28% (p=0.000 n=10) SpanWithEvents_WithStackTrace/AlwaysSample-12 446.3n ± 1% 395.8n ± 0% -11.30% (p=0.000 n=10) SpanWithEvents_WithStackTrace/NeverSample-12 170.4n ± 1% 161.4n ± 0% -5.25% (p=0.000 n=10) SpanWithEvents_WithTimestamp/AlwaysSample-12 441.9n ± 1% 379.1n ± 0% -14.19% (p=0.000 n=10) SpanWithEvents_WithTimestamp/NeverSample-12 196.3n ± 5% 185.2n ± 1% -5.65% (p=0.000 n=10) TraceID_DotString-12 43.07n ± 1% 40.19n ± 0% -6.69% (p=0.000 n=10) SpanID_DotString-12 31.61n ± 1% 32.63n ± 0% +3.23% (p=0.001 n=10) SpanProcessorOnEnd/batch:_10,_spans:_10-12 163.3n ± 3% 162.3n ± 0% -0.64% (p=0.010 n=10) SpanProcessorOnEnd/batch:_10,_spans:_100-12 1.645µ ± 1% 1.624µ ± 0% -1.31% (p=0.000 n=10) SpanProcessorOnEnd/batch:_100,_spans:_10-12 162.2n ± 1% 162.5n ± 0% ~ (p=0.587 n=10) SpanProcessorOnEnd/batch:_100,_spans:_100-12 1.626µ ± 1% 1.623µ ± 0% ~ (p=0.361 n=10) SpanProcessorVerboseLogging-12 6.795µ ± 2% 5.789µ ± 3% -14.81% (p=0.000 n=10) geomean 225.5n 211.6n -6.19% │ private/base2.txt │ private/new2.txt │ │ B/op │ B/op vs base │ Truncate/Unlimited-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Zero-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Short-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ASCII-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ValidUTF-8-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/InvalidUTF-8-12 16.00 ± 0% 16.00 ± 0% ~ (p=1.000 n=10) ¹ Truncate/MixedUTF-8-12 32.00 ± 0% 32.00 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/false-12 6.891Ki ± 0% 6.859Ki ± 0% -0.45% (p=0.000 n=10) RecordingSpanSetAttributes/WithLimit/true-12 7.023Ki ± 0% 6.992Ki ± 0% -0.44% (p=0.000 n=10) SpanEnd-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_a_simple_span-12 528.0 ± 0% 496.0 ± 0% -6.06% (p=0.000 n=10) TraceStart/with_several_links-12 704.0 ± 0% 672.0 ± 0% -4.55% (p=0.000 n=10) TraceStart/with_attributes-12 784.0 ± 0% 752.0 ± 0% -4.08% (p=0.000 n=10) SpanLimits/AttributeValueLengthLimit-12 10.56Ki ± 0% 10.53Ki ± 0% -0.30% (p=0.000 n=10) SpanLimits/AttributeCountLimit-12 9.844Ki ± 0% 9.812Ki ± 0% -0.32% (p=0.000 n=10) SpanLimits/EventCountLimit-12 9.422Ki ± 0% 9.391Ki ± 0% -0.33% (p=0.000 n=10) SpanLimits/LinkCountLimit-12 9.031Ki ± 0% 9.000Ki ± 0% -0.35% (p=0.000 n=10) SpanLimits/AttributePerEventCountLimit-12 10.47Ki ± 0% 10.44Ki ± 0% -0.30% (p=0.000 n=10) SpanLimits/AttributePerLinkCountLimit-12 10.47Ki ± 0% 10.44Ki ± 0% -0.30% (p=0.000 n=10) SpanSetAttributesOverCapacity-12 592.0 ± 0% 560.0 ± 0% -5.41% (p=0.000 n=10) StartEndSpan/AlwaysSample-12 528.0 ± 0% 496.0 ± 0% -6.06% (p=0.000 n=10) StartEndSpan/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/AlwaysSample-12 1040.0 ± 0% 1008.0 ± 0% -3.08% (p=0.000 n=10) SpanWithAttributes_4/NeverSample-12 400.0 ± 0% 400.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/AlwaysSample-12 1.516Ki ± 0% 1.484Ki ± 0% -2.06% (p=0.000 n=10) SpanWithAttributes_8/NeverSample-12 656.0 ± 0% 656.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/AlwaysSample-12 1.141Ki ± 0% 1.109Ki ± 0% -2.74% (p=0.000 n=10) SpanWithAttributes_all/NeverSample-12 464.0 ± 0% 464.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/AlwaysSample-12 1.891Ki ± 0% 1.859Ki ± 0% -1.65% (p=0.000 n=10) SpanWithAttributes_all_2x/NeverSample-12 848.0 ± 0% 848.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/AlwaysSample-12 1040.0 ± 0% 1008.0 ± 0% -3.08% (p=0.000 n=10) SpanWithEvents_4/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/AlwaysSample-12 1.641Ki ± 0% 1.609Ki ± 0% -1.90% (p=0.000 n=10) SpanWithEvents_8/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/AlwaysSample-12 624.0 ± 0% 592.0 ± 0% -5.13% (p=0.000 n=10) SpanWithEvents_WithStackTrace/NeverSample-12 160.0 ± 0% 160.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/AlwaysSample-12 648.0 ± 0% 616.0 ± 0% -4.94% (p=0.000 n=10) SpanWithEvents_WithTimestamp/NeverSample-12 184.0 ± 0% 184.0 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorVerboseLogging-12 9.547Ki ± 0% 9.234Ki ± 0% -3.27% (p=0.000 n=10) geomean ² -1.34% ² ¹ all samples are equal ² summaries must be >0 to compute geomean │ private/base2.txt │ private/new2.txt │ │ allocs/op │ allocs/op vs base │ Truncate/Unlimited-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Zero-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Short-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ASCII-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ValidUTF-8-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/InvalidUTF-8-12 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/MixedUTF-8-12 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/false-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/true-12 10.00 ± 0% 10.00 ± 0% ~ (p=1.000 n=10) ¹ SpanEnd-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_a_simple_span-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_several_links-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_attributes-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributeValueLengthLimit-12 41.00 ± 0% 41.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributeCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/EventCountLimit-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/LinkCountLimit-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributePerEventCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributePerLinkCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanSetAttributesOverCapacity-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ StartEndSpan/AlwaysSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ StartEndSpan/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/AlwaysSample-12 5.000 ± 0% 5.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/AlwaysSample-12 6.000 ± 0% 6.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/AlwaysSample-12 5.000 ± 0% 5.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/NeverSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorVerboseLogging-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ geomean ² +0.00% ² ¹ all samples are equal ² summaries must be >0 to compute geomean See open-telemetry#6721.
Instead of using a mutex, use atomic compare-and-swap to set the endTime. Store unix nanoseconds as an int64 to enable atomics. This has few nice properties: - Span.End() no longer needs the mutex. The first call to Span.End() does an atomic compare-and-swap. Later calls will return early. - We remove the isRecording method and use the public IsRecording method since we don't need the mutex to access endTime. - We reduce the recordingSpan size by 32 bytes. time.Time takes 24 bytes compared to 8 bytes for int64 nanoseconds. We save 16 bytes each for startTime and endTime. Benchstat ``` benchstat private/base2.txt private/new2.txt goos: darwin goarch: arm64 pkg: go.opentelemetry.io/otel/sdk/trace cpu: Apple M2 Max │ private/base2.txt │ private/new2.txt │ │ sec/op │ sec/op vs base │ Truncate/Unlimited-12 0.2089n ± 2% 0.2090n ± 4% ~ (p=0.698 n=10) Truncate/Zero-12 0.3052n ± 1% 0.3087n ± 20% ~ (p=0.127 n=10) Truncate/Short-12 0.2081n ± 0% 0.2089n ± 1% ~ (p=0.362 n=10) Truncate/ASCII-12 0.7140n ± 2% 0.6855n ± 0% -4.00% (p=0.000 n=10) Truncate/ValidUTF-8-12 1.311n ± 2% 1.303n ± 1% -0.61% (p=0.015 n=10) Truncate/InvalidUTF-8-12 9.437n ± 1% 9.315n ± 3% ~ (p=0.143 n=10) Truncate/MixedUTF-8-12 17.32n ± 0% 17.16n ± 2% ~ (p=0.159 n=10) RecordingSpanSetAttributes/WithLimit/false-12 2.080µ ± 1% 2.010µ ± 1% -3.39% (p=0.000 n=10) RecordingSpanSetAttributes/WithLimit/true-12 4.358µ ± 0% 4.297µ ± 0% -1.40% (p=0.000 n=10) SpanEnd-12 107.90n ± 10% 94.44n ± 1% -12.47% (p=0.001 n=10) TraceStart/with_a_simple_span-12 319.5n ± 6% 293.7n ± 3% -8.08% (p=0.000 n=10) TraceStart/with_several_links-12 428.3n ± 2% 411.2n ± 1% -3.99% (p=0.000 n=10) TraceStart/with_attributes-12 469.6n ± 3% 430.4n ± 1% -8.35% (p=0.000 n=10) SpanLimits/AttributeValueLengthLimit-12 4.379µ ± 1% 4.144µ ± 1% -5.38% (p=0.000 n=10) SpanLimits/AttributeCountLimit-12 4.219µ ± 2% 3.909µ ± 1% -7.36% (p=0.000 n=10) SpanLimits/EventCountLimit-12 3.994µ ± 6% 3.663µ ± 1% -8.28% (p=0.000 n=10) SpanLimits/LinkCountLimit-12 3.835µ ± 2% 3.619µ ± 1% -5.63% (p=0.000 n=10) SpanLimits/AttributePerEventCountLimit-12 4.225µ ± 3% 3.961µ ± 1% -6.25% (p=0.000 n=10) SpanLimits/AttributePerLinkCountLimit-12 4.218µ ± 1% 3.951µ ± 1% -6.32% (p=0.000 n=10) SpanSetAttributesOverCapacity-12 1.676µ ± 2% 1.582µ ± 0% -5.58% (p=0.000 n=10) StartEndSpan/AlwaysSample-12 322.3n ± 0% 279.1n ± 0% -13.40% (p=0.000 n=10) StartEndSpan/NeverSample-12 153.5n ± 4% 148.1n ± 0% -3.55% (p=0.000 n=10) SpanWithAttributes_4/AlwaysSample-12 527.6n ± 1% 467.7n ± 0% -11.36% (p=0.000 n=10) SpanWithAttributes_4/NeverSample-12 245.1n ± 0% 227.6n ± 0% -7.14% (p=0.000 n=10) SpanWithAttributes_8/AlwaysSample-12 702.7n ± 2% 638.2n ± 1% -9.19% (p=0.000 n=10) SpanWithAttributes_8/NeverSample-12 336.4n ± 1% 305.0n ± 1% -9.32% (p=0.000 n=10) SpanWithAttributes_all/AlwaysSample-12 593.9n ± 3% 518.8n ± 1% -12.65% (p=0.000 n=10) SpanWithAttributes_all/NeverSample-12 267.0n ± 3% 251.6n ± 0% -5.73% (p=0.000 n=10) SpanWithAttributes_all_2x/AlwaysSample-12 850.2n ± 1% 749.9n ± 0% -11.80% (p=0.000 n=10) SpanWithAttributes_all_2x/NeverSample-12 398.4n ± 2% 350.8n ± 2% -11.95% (p=0.000 n=10) SpanWithEvents_4/AlwaysSample-12 736.3n ± 9% 640.9n ± 0% -12.96% (p=0.000 n=10) SpanWithEvents_4/NeverSample-12 158.1n ± 3% 149.8n ± 0% -5.25% (p=0.000 n=10) SpanWithEvents_8/AlwaysSample-12 1111.5n ± 1% 995.0n ± 0% -10.48% (p=0.000 n=10) SpanWithEvents_8/NeverSample-12 159.9n ± 2% 153.1n ± 0% -4.28% (p=0.000 n=10) SpanWithEvents_WithStackTrace/AlwaysSample-12 446.3n ± 1% 395.8n ± 0% -11.30% (p=0.000 n=10) SpanWithEvents_WithStackTrace/NeverSample-12 170.4n ± 1% 161.4n ± 0% -5.25% (p=0.000 n=10) SpanWithEvents_WithTimestamp/AlwaysSample-12 441.9n ± 1% 379.1n ± 0% -14.19% (p=0.000 n=10) SpanWithEvents_WithTimestamp/NeverSample-12 196.3n ± 5% 185.2n ± 1% -5.65% (p=0.000 n=10) TraceID_DotString-12 43.07n ± 1% 40.19n ± 0% -6.69% (p=0.000 n=10) SpanID_DotString-12 31.61n ± 1% 32.63n ± 0% +3.23% (p=0.001 n=10) SpanProcessorOnEnd/batch:_10,_spans:_10-12 163.3n ± 3% 162.3n ± 0% -0.64% (p=0.010 n=10) SpanProcessorOnEnd/batch:_10,_spans:_100-12 1.645µ ± 1% 1.624µ ± 0% -1.31% (p=0.000 n=10) SpanProcessorOnEnd/batch:_100,_spans:_10-12 162.2n ± 1% 162.5n ± 0% ~ (p=0.587 n=10) SpanProcessorOnEnd/batch:_100,_spans:_100-12 1.626µ ± 1% 1.623µ ± 0% ~ (p=0.361 n=10) SpanProcessorVerboseLogging-12 6.795µ ± 2% 5.789µ ± 3% -14.81% (p=0.000 n=10) geomean 225.5n 211.6n -6.19% │ private/base2.txt │ private/new2.txt │ │ B/op │ B/op vs base │ Truncate/Unlimited-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Zero-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Short-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ASCII-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ValidUTF-8-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/InvalidUTF-8-12 16.00 ± 0% 16.00 ± 0% ~ (p=1.000 n=10) ¹ Truncate/MixedUTF-8-12 32.00 ± 0% 32.00 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/false-12 6.891Ki ± 0% 6.859Ki ± 0% -0.45% (p=0.000 n=10) RecordingSpanSetAttributes/WithLimit/true-12 7.023Ki ± 0% 6.992Ki ± 0% -0.44% (p=0.000 n=10) SpanEnd-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_a_simple_span-12 528.0 ± 0% 496.0 ± 0% -6.06% (p=0.000 n=10) TraceStart/with_several_links-12 704.0 ± 0% 672.0 ± 0% -4.55% (p=0.000 n=10) TraceStart/with_attributes-12 784.0 ± 0% 752.0 ± 0% -4.08% (p=0.000 n=10) SpanLimits/AttributeValueLengthLimit-12 10.56Ki ± 0% 10.53Ki ± 0% -0.30% (p=0.000 n=10) SpanLimits/AttributeCountLimit-12 9.844Ki ± 0% 9.812Ki ± 0% -0.32% (p=0.000 n=10) SpanLimits/EventCountLimit-12 9.422Ki ± 0% 9.391Ki ± 0% -0.33% (p=0.000 n=10) SpanLimits/LinkCountLimit-12 9.031Ki ± 0% 9.000Ki ± 0% -0.35% (p=0.000 n=10) SpanLimits/AttributePerEventCountLimit-12 10.47Ki ± 0% 10.44Ki ± 0% -0.30% (p=0.000 n=10) SpanLimits/AttributePerLinkCountLimit-12 10.47Ki ± 0% 10.44Ki ± 0% -0.30% (p=0.000 n=10) SpanSetAttributesOverCapacity-12 592.0 ± 0% 560.0 ± 0% -5.41% (p=0.000 n=10) StartEndSpan/AlwaysSample-12 528.0 ± 0% 496.0 ± 0% -6.06% (p=0.000 n=10) StartEndSpan/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/AlwaysSample-12 1040.0 ± 0% 1008.0 ± 0% -3.08% (p=0.000 n=10) SpanWithAttributes_4/NeverSample-12 400.0 ± 0% 400.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/AlwaysSample-12 1.516Ki ± 0% 1.484Ki ± 0% -2.06% (p=0.000 n=10) SpanWithAttributes_8/NeverSample-12 656.0 ± 0% 656.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/AlwaysSample-12 1.141Ki ± 0% 1.109Ki ± 0% -2.74% (p=0.000 n=10) SpanWithAttributes_all/NeverSample-12 464.0 ± 0% 464.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/AlwaysSample-12 1.891Ki ± 0% 1.859Ki ± 0% -1.65% (p=0.000 n=10) SpanWithAttributes_all_2x/NeverSample-12 848.0 ± 0% 848.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/AlwaysSample-12 1040.0 ± 0% 1008.0 ± 0% -3.08% (p=0.000 n=10) SpanWithEvents_4/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/AlwaysSample-12 1.641Ki ± 0% 1.609Ki ± 0% -1.90% (p=0.000 n=10) SpanWithEvents_8/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/AlwaysSample-12 624.0 ± 0% 592.0 ± 0% -5.13% (p=0.000 n=10) SpanWithEvents_WithStackTrace/NeverSample-12 160.0 ± 0% 160.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/AlwaysSample-12 648.0 ± 0% 616.0 ± 0% -4.94% (p=0.000 n=10) SpanWithEvents_WithTimestamp/NeverSample-12 184.0 ± 0% 184.0 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorVerboseLogging-12 9.547Ki ± 0% 9.234Ki ± 0% -3.27% (p=0.000 n=10) geomean ² -1.34% ² ¹ all samples are equal ² summaries must be >0 to compute geomean │ private/base2.txt │ private/new2.txt │ │ allocs/op │ allocs/op vs base │ Truncate/Unlimited-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Zero-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Short-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ASCII-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ValidUTF-8-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/InvalidUTF-8-12 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/MixedUTF-8-12 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/false-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/true-12 10.00 ± 0% 10.00 ± 0% ~ (p=1.000 n=10) ¹ SpanEnd-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_a_simple_span-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_several_links-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_attributes-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributeValueLengthLimit-12 41.00 ± 0% 41.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributeCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/EventCountLimit-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/LinkCountLimit-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributePerEventCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributePerLinkCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanSetAttributesOverCapacity-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ StartEndSpan/AlwaysSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ StartEndSpan/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/AlwaysSample-12 5.000 ± 0% 5.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/AlwaysSample-12 6.000 ± 0% 6.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/AlwaysSample-12 5.000 ± 0% 5.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/NeverSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorVerboseLogging-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ geomean ² +0.00% ² ¹ all samples are equal ² summaries must be >0 to compute geomean ``` See open-telemetry#6721.
Instead of using a mutex, use atomic compare-and-swap to set the endTime. Store unix nanoseconds as an int64 to enable atomics. This has few nice properties: - Span.End() no longer needs the mutex. The first call to Span.End() does an atomic compare-and-swap. Later calls will return early. - We remove the isRecording method and use the public IsRecording method since we don't need the mutex to access endTime. - We reduce the recordingSpan size by 32 bytes. time.Time takes 24 bytes compared to 8 bytes for int64 nanoseconds. We save 16 bytes each for startTime and endTime. Benchstat ``` benchstat private/base2.txt private/new2.txt goos: darwin goarch: arm64 pkg: go.opentelemetry.io/otel/sdk/trace cpu: Apple M2 Max │ private/base2.txt │ private/new2.txt │ │ sec/op │ sec/op vs base │ Truncate/Unlimited-12 0.2089n ± 2% 0.2090n ± 4% ~ (p=0.698 n=10) Truncate/Zero-12 0.3052n ± 1% 0.3087n ± 20% ~ (p=0.127 n=10) Truncate/Short-12 0.2081n ± 0% 0.2089n ± 1% ~ (p=0.362 n=10) Truncate/ASCII-12 0.7140n ± 2% 0.6855n ± 0% -4.00% (p=0.000 n=10) Truncate/ValidUTF-8-12 1.311n ± 2% 1.303n ± 1% -0.61% (p=0.015 n=10) Truncate/InvalidUTF-8-12 9.437n ± 1% 9.315n ± 3% ~ (p=0.143 n=10) Truncate/MixedUTF-8-12 17.32n ± 0% 17.16n ± 2% ~ (p=0.159 n=10) RecordingSpanSetAttributes/WithLimit/false-12 2.080µ ± 1% 2.010µ ± 1% -3.39% (p=0.000 n=10) RecordingSpanSetAttributes/WithLimit/true-12 4.358µ ± 0% 4.297µ ± 0% -1.40% (p=0.000 n=10) SpanEnd-12 107.90n ± 10% 94.44n ± 1% -12.47% (p=0.001 n=10) TraceStart/with_a_simple_span-12 319.5n ± 6% 293.7n ± 3% -8.08% (p=0.000 n=10) TraceStart/with_several_links-12 428.3n ± 2% 411.2n ± 1% -3.99% (p=0.000 n=10) TraceStart/with_attributes-12 469.6n ± 3% 430.4n ± 1% -8.35% (p=0.000 n=10) SpanLimits/AttributeValueLengthLimit-12 4.379µ ± 1% 4.144µ ± 1% -5.38% (p=0.000 n=10) SpanLimits/AttributeCountLimit-12 4.219µ ± 2% 3.909µ ± 1% -7.36% (p=0.000 n=10) SpanLimits/EventCountLimit-12 3.994µ ± 6% 3.663µ ± 1% -8.28% (p=0.000 n=10) SpanLimits/LinkCountLimit-12 3.835µ ± 2% 3.619µ ± 1% -5.63% (p=0.000 n=10) SpanLimits/AttributePerEventCountLimit-12 4.225µ ± 3% 3.961µ ± 1% -6.25% (p=0.000 n=10) SpanLimits/AttributePerLinkCountLimit-12 4.218µ ± 1% 3.951µ ± 1% -6.32% (p=0.000 n=10) SpanSetAttributesOverCapacity-12 1.676µ ± 2% 1.582µ ± 0% -5.58% (p=0.000 n=10) StartEndSpan/AlwaysSample-12 322.3n ± 0% 279.1n ± 0% -13.40% (p=0.000 n=10) StartEndSpan/NeverSample-12 153.5n ± 4% 148.1n ± 0% -3.55% (p=0.000 n=10) SpanWithAttributes_4/AlwaysSample-12 527.6n ± 1% 467.7n ± 0% -11.36% (p=0.000 n=10) SpanWithAttributes_4/NeverSample-12 245.1n ± 0% 227.6n ± 0% -7.14% (p=0.000 n=10) SpanWithAttributes_8/AlwaysSample-12 702.7n ± 2% 638.2n ± 1% -9.19% (p=0.000 n=10) SpanWithAttributes_8/NeverSample-12 336.4n ± 1% 305.0n ± 1% -9.32% (p=0.000 n=10) SpanWithAttributes_all/AlwaysSample-12 593.9n ± 3% 518.8n ± 1% -12.65% (p=0.000 n=10) SpanWithAttributes_all/NeverSample-12 267.0n ± 3% 251.6n ± 0% -5.73% (p=0.000 n=10) SpanWithAttributes_all_2x/AlwaysSample-12 850.2n ± 1% 749.9n ± 0% -11.80% (p=0.000 n=10) SpanWithAttributes_all_2x/NeverSample-12 398.4n ± 2% 350.8n ± 2% -11.95% (p=0.000 n=10) SpanWithEvents_4/AlwaysSample-12 736.3n ± 9% 640.9n ± 0% -12.96% (p=0.000 n=10) SpanWithEvents_4/NeverSample-12 158.1n ± 3% 149.8n ± 0% -5.25% (p=0.000 n=10) SpanWithEvents_8/AlwaysSample-12 1111.5n ± 1% 995.0n ± 0% -10.48% (p=0.000 n=10) SpanWithEvents_8/NeverSample-12 159.9n ± 2% 153.1n ± 0% -4.28% (p=0.000 n=10) SpanWithEvents_WithStackTrace/AlwaysSample-12 446.3n ± 1% 395.8n ± 0% -11.30% (p=0.000 n=10) SpanWithEvents_WithStackTrace/NeverSample-12 170.4n ± 1% 161.4n ± 0% -5.25% (p=0.000 n=10) SpanWithEvents_WithTimestamp/AlwaysSample-12 441.9n ± 1% 379.1n ± 0% -14.19% (p=0.000 n=10) SpanWithEvents_WithTimestamp/NeverSample-12 196.3n ± 5% 185.2n ± 1% -5.65% (p=0.000 n=10) TraceID_DotString-12 43.07n ± 1% 40.19n ± 0% -6.69% (p=0.000 n=10) SpanID_DotString-12 31.61n ± 1% 32.63n ± 0% +3.23% (p=0.001 n=10) SpanProcessorOnEnd/batch:_10,_spans:_10-12 163.3n ± 3% 162.3n ± 0% -0.64% (p=0.010 n=10) SpanProcessorOnEnd/batch:_10,_spans:_100-12 1.645µ ± 1% 1.624µ ± 0% -1.31% (p=0.000 n=10) SpanProcessorOnEnd/batch:_100,_spans:_10-12 162.2n ± 1% 162.5n ± 0% ~ (p=0.587 n=10) SpanProcessorOnEnd/batch:_100,_spans:_100-12 1.626µ ± 1% 1.623µ ± 0% ~ (p=0.361 n=10) SpanProcessorVerboseLogging-12 6.795µ ± 2% 5.789µ ± 3% -14.81% (p=0.000 n=10) geomean 225.5n 211.6n -6.19% │ private/base2.txt │ private/new2.txt │ │ B/op │ B/op vs base │ Truncate/Unlimited-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Zero-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Short-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ASCII-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ValidUTF-8-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/InvalidUTF-8-12 16.00 ± 0% 16.00 ± 0% ~ (p=1.000 n=10) ¹ Truncate/MixedUTF-8-12 32.00 ± 0% 32.00 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/false-12 6.891Ki ± 0% 6.859Ki ± 0% -0.45% (p=0.000 n=10) RecordingSpanSetAttributes/WithLimit/true-12 7.023Ki ± 0% 6.992Ki ± 0% -0.44% (p=0.000 n=10) SpanEnd-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_a_simple_span-12 528.0 ± 0% 496.0 ± 0% -6.06% (p=0.000 n=10) TraceStart/with_several_links-12 704.0 ± 0% 672.0 ± 0% -4.55% (p=0.000 n=10) TraceStart/with_attributes-12 784.0 ± 0% 752.0 ± 0% -4.08% (p=0.000 n=10) SpanLimits/AttributeValueLengthLimit-12 10.56Ki ± 0% 10.53Ki ± 0% -0.30% (p=0.000 n=10) SpanLimits/AttributeCountLimit-12 9.844Ki ± 0% 9.812Ki ± 0% -0.32% (p=0.000 n=10) SpanLimits/EventCountLimit-12 9.422Ki ± 0% 9.391Ki ± 0% -0.33% (p=0.000 n=10) SpanLimits/LinkCountLimit-12 9.031Ki ± 0% 9.000Ki ± 0% -0.35% (p=0.000 n=10) SpanLimits/AttributePerEventCountLimit-12 10.47Ki ± 0% 10.44Ki ± 0% -0.30% (p=0.000 n=10) SpanLimits/AttributePerLinkCountLimit-12 10.47Ki ± 0% 10.44Ki ± 0% -0.30% (p=0.000 n=10) SpanSetAttributesOverCapacity-12 592.0 ± 0% 560.0 ± 0% -5.41% (p=0.000 n=10) StartEndSpan/AlwaysSample-12 528.0 ± 0% 496.0 ± 0% -6.06% (p=0.000 n=10) StartEndSpan/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/AlwaysSample-12 1040.0 ± 0% 1008.0 ± 0% -3.08% (p=0.000 n=10) SpanWithAttributes_4/NeverSample-12 400.0 ± 0% 400.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/AlwaysSample-12 1.516Ki ± 0% 1.484Ki ± 0% -2.06% (p=0.000 n=10) SpanWithAttributes_8/NeverSample-12 656.0 ± 0% 656.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/AlwaysSample-12 1.141Ki ± 0% 1.109Ki ± 0% -2.74% (p=0.000 n=10) SpanWithAttributes_all/NeverSample-12 464.0 ± 0% 464.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/AlwaysSample-12 1.891Ki ± 0% 1.859Ki ± 0% -1.65% (p=0.000 n=10) SpanWithAttributes_all_2x/NeverSample-12 848.0 ± 0% 848.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/AlwaysSample-12 1040.0 ± 0% 1008.0 ± 0% -3.08% (p=0.000 n=10) SpanWithEvents_4/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/AlwaysSample-12 1.641Ki ± 0% 1.609Ki ± 0% -1.90% (p=0.000 n=10) SpanWithEvents_8/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/AlwaysSample-12 624.0 ± 0% 592.0 ± 0% -5.13% (p=0.000 n=10) SpanWithEvents_WithStackTrace/NeverSample-12 160.0 ± 0% 160.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/AlwaysSample-12 648.0 ± 0% 616.0 ± 0% -4.94% (p=0.000 n=10) SpanWithEvents_WithTimestamp/NeverSample-12 184.0 ± 0% 184.0 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorVerboseLogging-12 9.547Ki ± 0% 9.234Ki ± 0% -3.27% (p=0.000 n=10) geomean ² -1.34% ² ¹ all samples are equal ² summaries must be >0 to compute geomean │ private/base2.txt │ private/new2.txt │ │ allocs/op │ allocs/op vs base │ Truncate/Unlimited-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Zero-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Short-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ASCII-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ValidUTF-8-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/InvalidUTF-8-12 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/MixedUTF-8-12 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/false-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/true-12 10.00 ± 0% 10.00 ± 0% ~ (p=1.000 n=10) ¹ SpanEnd-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_a_simple_span-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_several_links-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_attributes-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributeValueLengthLimit-12 41.00 ± 0% 41.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributeCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/EventCountLimit-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/LinkCountLimit-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributePerEventCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributePerLinkCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanSetAttributesOverCapacity-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ StartEndSpan/AlwaysSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ StartEndSpan/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/AlwaysSample-12 5.000 ± 0% 5.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/AlwaysSample-12 6.000 ± 0% 6.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/AlwaysSample-12 5.000 ± 0% 5.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/NeverSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorVerboseLogging-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ geomean ² +0.00% ² ¹ all samples are equal ² summaries must be >0 to compute geomean ``` See open-telemetry#6721.
Instead of using a mutex, use atomic compare-and-swap to set the endTime. Store unix nanoseconds as an int64 to enable atomics. This has few nice properties: - Span.End() no longer needs the mutex. The first call to Span.End() does an atomic compare-and-swap. Later calls will return early. - We remove the isRecording method and use the public IsRecording method since we don't need the mutex to access endTime. - We reduce the recordingSpan size by 32 bytes. time.Time takes 24 bytes compared to 8 bytes for int64 nanoseconds. We save 16 bytes each for startTime and endTime. Benchstat ``` benchstat private/base2.txt private/new2.txt goos: darwin goarch: arm64 pkg: go.opentelemetry.io/otel/sdk/trace cpu: Apple M2 Max │ private/base2.txt │ private/new2.txt │ │ sec/op │ sec/op vs base │ Truncate/Unlimited-12 0.2089n ± 2% 0.2090n ± 4% ~ (p=0.698 n=10) Truncate/Zero-12 0.3052n ± 1% 0.3087n ± 20% ~ (p=0.127 n=10) Truncate/Short-12 0.2081n ± 0% 0.2089n ± 1% ~ (p=0.362 n=10) Truncate/ASCII-12 0.7140n ± 2% 0.6855n ± 0% -4.00% (p=0.000 n=10) Truncate/ValidUTF-8-12 1.311n ± 2% 1.303n ± 1% -0.61% (p=0.015 n=10) Truncate/InvalidUTF-8-12 9.437n ± 1% 9.315n ± 3% ~ (p=0.143 n=10) Truncate/MixedUTF-8-12 17.32n ± 0% 17.16n ± 2% ~ (p=0.159 n=10) RecordingSpanSetAttributes/WithLimit/false-12 2.080µ ± 1% 2.010µ ± 1% -3.39% (p=0.000 n=10) RecordingSpanSetAttributes/WithLimit/true-12 4.358µ ± 0% 4.297µ ± 0% -1.40% (p=0.000 n=10) SpanEnd-12 107.90n ± 10% 94.44n ± 1% -12.47% (p=0.001 n=10) TraceStart/with_a_simple_span-12 319.5n ± 6% 293.7n ± 3% -8.08% (p=0.000 n=10) TraceStart/with_several_links-12 428.3n ± 2% 411.2n ± 1% -3.99% (p=0.000 n=10) TraceStart/with_attributes-12 469.6n ± 3% 430.4n ± 1% -8.35% (p=0.000 n=10) SpanLimits/AttributeValueLengthLimit-12 4.379µ ± 1% 4.144µ ± 1% -5.38% (p=0.000 n=10) SpanLimits/AttributeCountLimit-12 4.219µ ± 2% 3.909µ ± 1% -7.36% (p=0.000 n=10) SpanLimits/EventCountLimit-12 3.994µ ± 6% 3.663µ ± 1% -8.28% (p=0.000 n=10) SpanLimits/LinkCountLimit-12 3.835µ ± 2% 3.619µ ± 1% -5.63% (p=0.000 n=10) SpanLimits/AttributePerEventCountLimit-12 4.225µ ± 3% 3.961µ ± 1% -6.25% (p=0.000 n=10) SpanLimits/AttributePerLinkCountLimit-12 4.218µ ± 1% 3.951µ ± 1% -6.32% (p=0.000 n=10) SpanSetAttributesOverCapacity-12 1.676µ ± 2% 1.582µ ± 0% -5.58% (p=0.000 n=10) StartEndSpan/AlwaysSample-12 322.3n ± 0% 279.1n ± 0% -13.40% (p=0.000 n=10) StartEndSpan/NeverSample-12 153.5n ± 4% 148.1n ± 0% -3.55% (p=0.000 n=10) SpanWithAttributes_4/AlwaysSample-12 527.6n ± 1% 467.7n ± 0% -11.36% (p=0.000 n=10) SpanWithAttributes_4/NeverSample-12 245.1n ± 0% 227.6n ± 0% -7.14% (p=0.000 n=10) SpanWithAttributes_8/AlwaysSample-12 702.7n ± 2% 638.2n ± 1% -9.19% (p=0.000 n=10) SpanWithAttributes_8/NeverSample-12 336.4n ± 1% 305.0n ± 1% -9.32% (p=0.000 n=10) SpanWithAttributes_all/AlwaysSample-12 593.9n ± 3% 518.8n ± 1% -12.65% (p=0.000 n=10) SpanWithAttributes_all/NeverSample-12 267.0n ± 3% 251.6n ± 0% -5.73% (p=0.000 n=10) SpanWithAttributes_all_2x/AlwaysSample-12 850.2n ± 1% 749.9n ± 0% -11.80% (p=0.000 n=10) SpanWithAttributes_all_2x/NeverSample-12 398.4n ± 2% 350.8n ± 2% -11.95% (p=0.000 n=10) SpanWithEvents_4/AlwaysSample-12 736.3n ± 9% 640.9n ± 0% -12.96% (p=0.000 n=10) SpanWithEvents_4/NeverSample-12 158.1n ± 3% 149.8n ± 0% -5.25% (p=0.000 n=10) SpanWithEvents_8/AlwaysSample-12 1111.5n ± 1% 995.0n ± 0% -10.48% (p=0.000 n=10) SpanWithEvents_8/NeverSample-12 159.9n ± 2% 153.1n ± 0% -4.28% (p=0.000 n=10) SpanWithEvents_WithStackTrace/AlwaysSample-12 446.3n ± 1% 395.8n ± 0% -11.30% (p=0.000 n=10) SpanWithEvents_WithStackTrace/NeverSample-12 170.4n ± 1% 161.4n ± 0% -5.25% (p=0.000 n=10) SpanWithEvents_WithTimestamp/AlwaysSample-12 441.9n ± 1% 379.1n ± 0% -14.19% (p=0.000 n=10) SpanWithEvents_WithTimestamp/NeverSample-12 196.3n ± 5% 185.2n ± 1% -5.65% (p=0.000 n=10) TraceID_DotString-12 43.07n ± 1% 40.19n ± 0% -6.69% (p=0.000 n=10) SpanID_DotString-12 31.61n ± 1% 32.63n ± 0% +3.23% (p=0.001 n=10) SpanProcessorOnEnd/batch:_10,_spans:_10-12 163.3n ± 3% 162.3n ± 0% -0.64% (p=0.010 n=10) SpanProcessorOnEnd/batch:_10,_spans:_100-12 1.645µ ± 1% 1.624µ ± 0% -1.31% (p=0.000 n=10) SpanProcessorOnEnd/batch:_100,_spans:_10-12 162.2n ± 1% 162.5n ± 0% ~ (p=0.587 n=10) SpanProcessorOnEnd/batch:_100,_spans:_100-12 1.626µ ± 1% 1.623µ ± 0% ~ (p=0.361 n=10) SpanProcessorVerboseLogging-12 6.795µ ± 2% 5.789µ ± 3% -14.81% (p=0.000 n=10) geomean 225.5n 211.6n -6.19% │ private/base2.txt │ private/new2.txt │ │ B/op │ B/op vs base │ Truncate/Unlimited-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Zero-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Short-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ASCII-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ValidUTF-8-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/InvalidUTF-8-12 16.00 ± 0% 16.00 ± 0% ~ (p=1.000 n=10) ¹ Truncate/MixedUTF-8-12 32.00 ± 0% 32.00 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/false-12 6.891Ki ± 0% 6.859Ki ± 0% -0.45% (p=0.000 n=10) RecordingSpanSetAttributes/WithLimit/true-12 7.023Ki ± 0% 6.992Ki ± 0% -0.44% (p=0.000 n=10) SpanEnd-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_a_simple_span-12 528.0 ± 0% 496.0 ± 0% -6.06% (p=0.000 n=10) TraceStart/with_several_links-12 704.0 ± 0% 672.0 ± 0% -4.55% (p=0.000 n=10) TraceStart/with_attributes-12 784.0 ± 0% 752.0 ± 0% -4.08% (p=0.000 n=10) SpanLimits/AttributeValueLengthLimit-12 10.56Ki ± 0% 10.53Ki ± 0% -0.30% (p=0.000 n=10) SpanLimits/AttributeCountLimit-12 9.844Ki ± 0% 9.812Ki ± 0% -0.32% (p=0.000 n=10) SpanLimits/EventCountLimit-12 9.422Ki ± 0% 9.391Ki ± 0% -0.33% (p=0.000 n=10) SpanLimits/LinkCountLimit-12 9.031Ki ± 0% 9.000Ki ± 0% -0.35% (p=0.000 n=10) SpanLimits/AttributePerEventCountLimit-12 10.47Ki ± 0% 10.44Ki ± 0% -0.30% (p=0.000 n=10) SpanLimits/AttributePerLinkCountLimit-12 10.47Ki ± 0% 10.44Ki ± 0% -0.30% (p=0.000 n=10) SpanSetAttributesOverCapacity-12 592.0 ± 0% 560.0 ± 0% -5.41% (p=0.000 n=10) StartEndSpan/AlwaysSample-12 528.0 ± 0% 496.0 ± 0% -6.06% (p=0.000 n=10) StartEndSpan/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/AlwaysSample-12 1040.0 ± 0% 1008.0 ± 0% -3.08% (p=0.000 n=10) SpanWithAttributes_4/NeverSample-12 400.0 ± 0% 400.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/AlwaysSample-12 1.516Ki ± 0% 1.484Ki ± 0% -2.06% (p=0.000 n=10) SpanWithAttributes_8/NeverSample-12 656.0 ± 0% 656.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/AlwaysSample-12 1.141Ki ± 0% 1.109Ki ± 0% -2.74% (p=0.000 n=10) SpanWithAttributes_all/NeverSample-12 464.0 ± 0% 464.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/AlwaysSample-12 1.891Ki ± 0% 1.859Ki ± 0% -1.65% (p=0.000 n=10) SpanWithAttributes_all_2x/NeverSample-12 848.0 ± 0% 848.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/AlwaysSample-12 1040.0 ± 0% 1008.0 ± 0% -3.08% (p=0.000 n=10) SpanWithEvents_4/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/AlwaysSample-12 1.641Ki ± 0% 1.609Ki ± 0% -1.90% (p=0.000 n=10) SpanWithEvents_8/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/AlwaysSample-12 624.0 ± 0% 592.0 ± 0% -5.13% (p=0.000 n=10) SpanWithEvents_WithStackTrace/NeverSample-12 160.0 ± 0% 160.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/AlwaysSample-12 648.0 ± 0% 616.0 ± 0% -4.94% (p=0.000 n=10) SpanWithEvents_WithTimestamp/NeverSample-12 184.0 ± 0% 184.0 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorVerboseLogging-12 9.547Ki ± 0% 9.234Ki ± 0% -3.27% (p=0.000 n=10) geomean ² -1.34% ² ¹ all samples are equal ² summaries must be >0 to compute geomean │ private/base2.txt │ private/new2.txt │ │ allocs/op │ allocs/op vs base │ Truncate/Unlimited-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Zero-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Short-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ASCII-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ValidUTF-8-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/InvalidUTF-8-12 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/MixedUTF-8-12 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/false-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/true-12 10.00 ± 0% 10.00 ± 0% ~ (p=1.000 n=10) ¹ SpanEnd-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_a_simple_span-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_several_links-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_attributes-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributeValueLengthLimit-12 41.00 ± 0% 41.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributeCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/EventCountLimit-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/LinkCountLimit-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributePerEventCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributePerLinkCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanSetAttributesOverCapacity-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ StartEndSpan/AlwaysSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ StartEndSpan/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/AlwaysSample-12 5.000 ± 0% 5.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/AlwaysSample-12 6.000 ± 0% 6.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/AlwaysSample-12 5.000 ± 0% 5.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/NeverSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorVerboseLogging-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ geomean ² +0.00% ² ¹ all samples are equal ² summaries must be >0 to compute geomean ``` See open-telemetry#6721.
Instead of using a mutex, use atomic compare-and-swap to set the endTime. Store unix nanoseconds as an int64 to enable atomics. This has few nice properties: - Span.End() no longer needs the mutex. The first call to Span.End() does an atomic compare-and-swap. Later calls will return early. - We remove the isRecording method and use the public IsRecording method since we don't need the mutex to access endTime. - We reduce the recordingSpan size by 32 bytes. time.Time takes 24 bytes compared to 8 bytes for int64 nanoseconds. We save 16 bytes each for startTime and endTime. Benchstat ``` benchstat private/base2.txt private/new2.txt goos: darwin goarch: arm64 pkg: go.opentelemetry.io/otel/sdk/trace cpu: Apple M2 Max │ private/base2.txt │ private/new2.txt │ │ sec/op │ sec/op vs base │ Truncate/Unlimited-12 0.2089n ± 2% 0.2090n ± 4% ~ (p=0.698 n=10) Truncate/Zero-12 0.3052n ± 1% 0.3087n ± 20% ~ (p=0.127 n=10) Truncate/Short-12 0.2081n ± 0% 0.2089n ± 1% ~ (p=0.362 n=10) Truncate/ASCII-12 0.7140n ± 2% 0.6855n ± 0% -4.00% (p=0.000 n=10) Truncate/ValidUTF-8-12 1.311n ± 2% 1.303n ± 1% -0.61% (p=0.015 n=10) Truncate/InvalidUTF-8-12 9.437n ± 1% 9.315n ± 3% ~ (p=0.143 n=10) Truncate/MixedUTF-8-12 17.32n ± 0% 17.16n ± 2% ~ (p=0.159 n=10) RecordingSpanSetAttributes/WithLimit/false-12 2.080µ ± 1% 2.010µ ± 1% -3.39% (p=0.000 n=10) RecordingSpanSetAttributes/WithLimit/true-12 4.358µ ± 0% 4.297µ ± 0% -1.40% (p=0.000 n=10) SpanEnd-12 107.90n ± 10% 94.44n ± 1% -12.47% (p=0.001 n=10) TraceStart/with_a_simple_span-12 319.5n ± 6% 293.7n ± 3% -8.08% (p=0.000 n=10) TraceStart/with_several_links-12 428.3n ± 2% 411.2n ± 1% -3.99% (p=0.000 n=10) TraceStart/with_attributes-12 469.6n ± 3% 430.4n ± 1% -8.35% (p=0.000 n=10) SpanLimits/AttributeValueLengthLimit-12 4.379µ ± 1% 4.144µ ± 1% -5.38% (p=0.000 n=10) SpanLimits/AttributeCountLimit-12 4.219µ ± 2% 3.909µ ± 1% -7.36% (p=0.000 n=10) SpanLimits/EventCountLimit-12 3.994µ ± 6% 3.663µ ± 1% -8.28% (p=0.000 n=10) SpanLimits/LinkCountLimit-12 3.835µ ± 2% 3.619µ ± 1% -5.63% (p=0.000 n=10) SpanLimits/AttributePerEventCountLimit-12 4.225µ ± 3% 3.961µ ± 1% -6.25% (p=0.000 n=10) SpanLimits/AttributePerLinkCountLimit-12 4.218µ ± 1% 3.951µ ± 1% -6.32% (p=0.000 n=10) SpanSetAttributesOverCapacity-12 1.676µ ± 2% 1.582µ ± 0% -5.58% (p=0.000 n=10) StartEndSpan/AlwaysSample-12 322.3n ± 0% 279.1n ± 0% -13.40% (p=0.000 n=10) StartEndSpan/NeverSample-12 153.5n ± 4% 148.1n ± 0% -3.55% (p=0.000 n=10) SpanWithAttributes_4/AlwaysSample-12 527.6n ± 1% 467.7n ± 0% -11.36% (p=0.000 n=10) SpanWithAttributes_4/NeverSample-12 245.1n ± 0% 227.6n ± 0% -7.14% (p=0.000 n=10) SpanWithAttributes_8/AlwaysSample-12 702.7n ± 2% 638.2n ± 1% -9.19% (p=0.000 n=10) SpanWithAttributes_8/NeverSample-12 336.4n ± 1% 305.0n ± 1% -9.32% (p=0.000 n=10) SpanWithAttributes_all/AlwaysSample-12 593.9n ± 3% 518.8n ± 1% -12.65% (p=0.000 n=10) SpanWithAttributes_all/NeverSample-12 267.0n ± 3% 251.6n ± 0% -5.73% (p=0.000 n=10) SpanWithAttributes_all_2x/AlwaysSample-12 850.2n ± 1% 749.9n ± 0% -11.80% (p=0.000 n=10) SpanWithAttributes_all_2x/NeverSample-12 398.4n ± 2% 350.8n ± 2% -11.95% (p=0.000 n=10) SpanWithEvents_4/AlwaysSample-12 736.3n ± 9% 640.9n ± 0% -12.96% (p=0.000 n=10) SpanWithEvents_4/NeverSample-12 158.1n ± 3% 149.8n ± 0% -5.25% (p=0.000 n=10) SpanWithEvents_8/AlwaysSample-12 1111.5n ± 1% 995.0n ± 0% -10.48% (p=0.000 n=10) SpanWithEvents_8/NeverSample-12 159.9n ± 2% 153.1n ± 0% -4.28% (p=0.000 n=10) SpanWithEvents_WithStackTrace/AlwaysSample-12 446.3n ± 1% 395.8n ± 0% -11.30% (p=0.000 n=10) SpanWithEvents_WithStackTrace/NeverSample-12 170.4n ± 1% 161.4n ± 0% -5.25% (p=0.000 n=10) SpanWithEvents_WithTimestamp/AlwaysSample-12 441.9n ± 1% 379.1n ± 0% -14.19% (p=0.000 n=10) SpanWithEvents_WithTimestamp/NeverSample-12 196.3n ± 5% 185.2n ± 1% -5.65% (p=0.000 n=10) TraceID_DotString-12 43.07n ± 1% 40.19n ± 0% -6.69% (p=0.000 n=10) SpanID_DotString-12 31.61n ± 1% 32.63n ± 0% +3.23% (p=0.001 n=10) SpanProcessorOnEnd/batch:_10,_spans:_10-12 163.3n ± 3% 162.3n ± 0% -0.64% (p=0.010 n=10) SpanProcessorOnEnd/batch:_10,_spans:_100-12 1.645µ ± 1% 1.624µ ± 0% -1.31% (p=0.000 n=10) SpanProcessorOnEnd/batch:_100,_spans:_10-12 162.2n ± 1% 162.5n ± 0% ~ (p=0.587 n=10) SpanProcessorOnEnd/batch:_100,_spans:_100-12 1.626µ ± 1% 1.623µ ± 0% ~ (p=0.361 n=10) SpanProcessorVerboseLogging-12 6.795µ ± 2% 5.789µ ± 3% -14.81% (p=0.000 n=10) geomean 225.5n 211.6n -6.19% │ private/base2.txt │ private/new2.txt │ │ B/op │ B/op vs base │ Truncate/Unlimited-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Zero-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Short-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ASCII-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ValidUTF-8-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/InvalidUTF-8-12 16.00 ± 0% 16.00 ± 0% ~ (p=1.000 n=10) ¹ Truncate/MixedUTF-8-12 32.00 ± 0% 32.00 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/false-12 6.891Ki ± 0% 6.859Ki ± 0% -0.45% (p=0.000 n=10) RecordingSpanSetAttributes/WithLimit/true-12 7.023Ki ± 0% 6.992Ki ± 0% -0.44% (p=0.000 n=10) SpanEnd-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_a_simple_span-12 528.0 ± 0% 496.0 ± 0% -6.06% (p=0.000 n=10) TraceStart/with_several_links-12 704.0 ± 0% 672.0 ± 0% -4.55% (p=0.000 n=10) TraceStart/with_attributes-12 784.0 ± 0% 752.0 ± 0% -4.08% (p=0.000 n=10) SpanLimits/AttributeValueLengthLimit-12 10.56Ki ± 0% 10.53Ki ± 0% -0.30% (p=0.000 n=10) SpanLimits/AttributeCountLimit-12 9.844Ki ± 0% 9.812Ki ± 0% -0.32% (p=0.000 n=10) SpanLimits/EventCountLimit-12 9.422Ki ± 0% 9.391Ki ± 0% -0.33% (p=0.000 n=10) SpanLimits/LinkCountLimit-12 9.031Ki ± 0% 9.000Ki ± 0% -0.35% (p=0.000 n=10) SpanLimits/AttributePerEventCountLimit-12 10.47Ki ± 0% 10.44Ki ± 0% -0.30% (p=0.000 n=10) SpanLimits/AttributePerLinkCountLimit-12 10.47Ki ± 0% 10.44Ki ± 0% -0.30% (p=0.000 n=10) SpanSetAttributesOverCapacity-12 592.0 ± 0% 560.0 ± 0% -5.41% (p=0.000 n=10) StartEndSpan/AlwaysSample-12 528.0 ± 0% 496.0 ± 0% -6.06% (p=0.000 n=10) StartEndSpan/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/AlwaysSample-12 1040.0 ± 0% 1008.0 ± 0% -3.08% (p=0.000 n=10) SpanWithAttributes_4/NeverSample-12 400.0 ± 0% 400.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/AlwaysSample-12 1.516Ki ± 0% 1.484Ki ± 0% -2.06% (p=0.000 n=10) SpanWithAttributes_8/NeverSample-12 656.0 ± 0% 656.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/AlwaysSample-12 1.141Ki ± 0% 1.109Ki ± 0% -2.74% (p=0.000 n=10) SpanWithAttributes_all/NeverSample-12 464.0 ± 0% 464.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/AlwaysSample-12 1.891Ki ± 0% 1.859Ki ± 0% -1.65% (p=0.000 n=10) SpanWithAttributes_all_2x/NeverSample-12 848.0 ± 0% 848.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/AlwaysSample-12 1040.0 ± 0% 1008.0 ± 0% -3.08% (p=0.000 n=10) SpanWithEvents_4/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/AlwaysSample-12 1.641Ki ± 0% 1.609Ki ± 0% -1.90% (p=0.000 n=10) SpanWithEvents_8/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/AlwaysSample-12 624.0 ± 0% 592.0 ± 0% -5.13% (p=0.000 n=10) SpanWithEvents_WithStackTrace/NeverSample-12 160.0 ± 0% 160.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/AlwaysSample-12 648.0 ± 0% 616.0 ± 0% -4.94% (p=0.000 n=10) SpanWithEvents_WithTimestamp/NeverSample-12 184.0 ± 0% 184.0 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorVerboseLogging-12 9.547Ki ± 0% 9.234Ki ± 0% -3.27% (p=0.000 n=10) geomean ² -1.34% ² ¹ all samples are equal ² summaries must be >0 to compute geomean │ private/base2.txt │ private/new2.txt │ │ allocs/op │ allocs/op vs base │ Truncate/Unlimited-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Zero-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Short-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ASCII-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ValidUTF-8-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/InvalidUTF-8-12 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/MixedUTF-8-12 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/false-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/true-12 10.00 ± 0% 10.00 ± 0% ~ (p=1.000 n=10) ¹ SpanEnd-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_a_simple_span-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_several_links-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_attributes-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributeValueLengthLimit-12 41.00 ± 0% 41.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributeCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/EventCountLimit-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/LinkCountLimit-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributePerEventCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributePerLinkCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanSetAttributesOverCapacity-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ StartEndSpan/AlwaysSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ StartEndSpan/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/AlwaysSample-12 5.000 ± 0% 5.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/AlwaysSample-12 6.000 ± 0% 6.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/AlwaysSample-12 5.000 ± 0% 5.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/NeverSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorVerboseLogging-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ geomean ² +0.00% ² ¹ all samples are equal ² summaries must be >0 to compute geomean ``` See open-telemetry#6721.
Instead of using a mutex, use atomic compare-and-swap to set the endTime. Store unix nanoseconds as an int64 to enable atomics. This has few nice properties: - Span.End() no longer needs the mutex. The first call to Span.End() does an atomic compare-and-swap. Later calls will return early. - We remove the isRecording method and use the public IsRecording method since we don't need the mutex to access endTime. - We reduce the recordingSpan size by 32 bytes. time.Time takes 24 bytes compared to 8 bytes for int64 nanoseconds. We save 16 bytes each for startTime and endTime. Benchstat ``` benchstat private/base2.txt private/new2.txt goos: darwin goarch: arm64 pkg: go.opentelemetry.io/otel/sdk/trace cpu: Apple M2 Max │ private/base2.txt │ private/new2.txt │ │ sec/op │ sec/op vs base │ Truncate/Unlimited-12 0.2089n ± 2% 0.2090n ± 4% ~ (p=0.698 n=10) Truncate/Zero-12 0.3052n ± 1% 0.3087n ± 20% ~ (p=0.127 n=10) Truncate/Short-12 0.2081n ± 0% 0.2089n ± 1% ~ (p=0.362 n=10) Truncate/ASCII-12 0.7140n ± 2% 0.6855n ± 0% -4.00% (p=0.000 n=10) Truncate/ValidUTF-8-12 1.311n ± 2% 1.303n ± 1% -0.61% (p=0.015 n=10) Truncate/InvalidUTF-8-12 9.437n ± 1% 9.315n ± 3% ~ (p=0.143 n=10) Truncate/MixedUTF-8-12 17.32n ± 0% 17.16n ± 2% ~ (p=0.159 n=10) RecordingSpanSetAttributes/WithLimit/false-12 2.080µ ± 1% 2.010µ ± 1% -3.39% (p=0.000 n=10) RecordingSpanSetAttributes/WithLimit/true-12 4.358µ ± 0% 4.297µ ± 0% -1.40% (p=0.000 n=10) SpanEnd-12 107.90n ± 10% 94.44n ± 1% -12.47% (p=0.001 n=10) TraceStart/with_a_simple_span-12 319.5n ± 6% 293.7n ± 3% -8.08% (p=0.000 n=10) TraceStart/with_several_links-12 428.3n ± 2% 411.2n ± 1% -3.99% (p=0.000 n=10) TraceStart/with_attributes-12 469.6n ± 3% 430.4n ± 1% -8.35% (p=0.000 n=10) SpanLimits/AttributeValueLengthLimit-12 4.379µ ± 1% 4.144µ ± 1% -5.38% (p=0.000 n=10) SpanLimits/AttributeCountLimit-12 4.219µ ± 2% 3.909µ ± 1% -7.36% (p=0.000 n=10) SpanLimits/EventCountLimit-12 3.994µ ± 6% 3.663µ ± 1% -8.28% (p=0.000 n=10) SpanLimits/LinkCountLimit-12 3.835µ ± 2% 3.619µ ± 1% -5.63% (p=0.000 n=10) SpanLimits/AttributePerEventCountLimit-12 4.225µ ± 3% 3.961µ ± 1% -6.25% (p=0.000 n=10) SpanLimits/AttributePerLinkCountLimit-12 4.218µ ± 1% 3.951µ ± 1% -6.32% (p=0.000 n=10) SpanSetAttributesOverCapacity-12 1.676µ ± 2% 1.582µ ± 0% -5.58% (p=0.000 n=10) StartEndSpan/AlwaysSample-12 322.3n ± 0% 279.1n ± 0% -13.40% (p=0.000 n=10) StartEndSpan/NeverSample-12 153.5n ± 4% 148.1n ± 0% -3.55% (p=0.000 n=10) SpanWithAttributes_4/AlwaysSample-12 527.6n ± 1% 467.7n ± 0% -11.36% (p=0.000 n=10) SpanWithAttributes_4/NeverSample-12 245.1n ± 0% 227.6n ± 0% -7.14% (p=0.000 n=10) SpanWithAttributes_8/AlwaysSample-12 702.7n ± 2% 638.2n ± 1% -9.19% (p=0.000 n=10) SpanWithAttributes_8/NeverSample-12 336.4n ± 1% 305.0n ± 1% -9.32% (p=0.000 n=10) SpanWithAttributes_all/AlwaysSample-12 593.9n ± 3% 518.8n ± 1% -12.65% (p=0.000 n=10) SpanWithAttributes_all/NeverSample-12 267.0n ± 3% 251.6n ± 0% -5.73% (p=0.000 n=10) SpanWithAttributes_all_2x/AlwaysSample-12 850.2n ± 1% 749.9n ± 0% -11.80% (p=0.000 n=10) SpanWithAttributes_all_2x/NeverSample-12 398.4n ± 2% 350.8n ± 2% -11.95% (p=0.000 n=10) SpanWithEvents_4/AlwaysSample-12 736.3n ± 9% 640.9n ± 0% -12.96% (p=0.000 n=10) SpanWithEvents_4/NeverSample-12 158.1n ± 3% 149.8n ± 0% -5.25% (p=0.000 n=10) SpanWithEvents_8/AlwaysSample-12 1111.5n ± 1% 995.0n ± 0% -10.48% (p=0.000 n=10) SpanWithEvents_8/NeverSample-12 159.9n ± 2% 153.1n ± 0% -4.28% (p=0.000 n=10) SpanWithEvents_WithStackTrace/AlwaysSample-12 446.3n ± 1% 395.8n ± 0% -11.30% (p=0.000 n=10) SpanWithEvents_WithStackTrace/NeverSample-12 170.4n ± 1% 161.4n ± 0% -5.25% (p=0.000 n=10) SpanWithEvents_WithTimestamp/AlwaysSample-12 441.9n ± 1% 379.1n ± 0% -14.19% (p=0.000 n=10) SpanWithEvents_WithTimestamp/NeverSample-12 196.3n ± 5% 185.2n ± 1% -5.65% (p=0.000 n=10) TraceID_DotString-12 43.07n ± 1% 40.19n ± 0% -6.69% (p=0.000 n=10) SpanID_DotString-12 31.61n ± 1% 32.63n ± 0% +3.23% (p=0.001 n=10) SpanProcessorOnEnd/batch:_10,_spans:_10-12 163.3n ± 3% 162.3n ± 0% -0.64% (p=0.010 n=10) SpanProcessorOnEnd/batch:_10,_spans:_100-12 1.645µ ± 1% 1.624µ ± 0% -1.31% (p=0.000 n=10) SpanProcessorOnEnd/batch:_100,_spans:_10-12 162.2n ± 1% 162.5n ± 0% ~ (p=0.587 n=10) SpanProcessorOnEnd/batch:_100,_spans:_100-12 1.626µ ± 1% 1.623µ ± 0% ~ (p=0.361 n=10) SpanProcessorVerboseLogging-12 6.795µ ± 2% 5.789µ ± 3% -14.81% (p=0.000 n=10) geomean 225.5n 211.6n -6.19% │ private/base2.txt │ private/new2.txt │ │ B/op │ B/op vs base │ Truncate/Unlimited-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Zero-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Short-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ASCII-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ValidUTF-8-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/InvalidUTF-8-12 16.00 ± 0% 16.00 ± 0% ~ (p=1.000 n=10) ¹ Truncate/MixedUTF-8-12 32.00 ± 0% 32.00 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/false-12 6.891Ki ± 0% 6.859Ki ± 0% -0.45% (p=0.000 n=10) RecordingSpanSetAttributes/WithLimit/true-12 7.023Ki ± 0% 6.992Ki ± 0% -0.44% (p=0.000 n=10) SpanEnd-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_a_simple_span-12 528.0 ± 0% 496.0 ± 0% -6.06% (p=0.000 n=10) TraceStart/with_several_links-12 704.0 ± 0% 672.0 ± 0% -4.55% (p=0.000 n=10) TraceStart/with_attributes-12 784.0 ± 0% 752.0 ± 0% -4.08% (p=0.000 n=10) SpanLimits/AttributeValueLengthLimit-12 10.56Ki ± 0% 10.53Ki ± 0% -0.30% (p=0.000 n=10) SpanLimits/AttributeCountLimit-12 9.844Ki ± 0% 9.812Ki ± 0% -0.32% (p=0.000 n=10) SpanLimits/EventCountLimit-12 9.422Ki ± 0% 9.391Ki ± 0% -0.33% (p=0.000 n=10) SpanLimits/LinkCountLimit-12 9.031Ki ± 0% 9.000Ki ± 0% -0.35% (p=0.000 n=10) SpanLimits/AttributePerEventCountLimit-12 10.47Ki ± 0% 10.44Ki ± 0% -0.30% (p=0.000 n=10) SpanLimits/AttributePerLinkCountLimit-12 10.47Ki ± 0% 10.44Ki ± 0% -0.30% (p=0.000 n=10) SpanSetAttributesOverCapacity-12 592.0 ± 0% 560.0 ± 0% -5.41% (p=0.000 n=10) StartEndSpan/AlwaysSample-12 528.0 ± 0% 496.0 ± 0% -6.06% (p=0.000 n=10) StartEndSpan/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/AlwaysSample-12 1040.0 ± 0% 1008.0 ± 0% -3.08% (p=0.000 n=10) SpanWithAttributes_4/NeverSample-12 400.0 ± 0% 400.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/AlwaysSample-12 1.516Ki ± 0% 1.484Ki ± 0% -2.06% (p=0.000 n=10) SpanWithAttributes_8/NeverSample-12 656.0 ± 0% 656.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/AlwaysSample-12 1.141Ki ± 0% 1.109Ki ± 0% -2.74% (p=0.000 n=10) SpanWithAttributes_all/NeverSample-12 464.0 ± 0% 464.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/AlwaysSample-12 1.891Ki ± 0% 1.859Ki ± 0% -1.65% (p=0.000 n=10) SpanWithAttributes_all_2x/NeverSample-12 848.0 ± 0% 848.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/AlwaysSample-12 1040.0 ± 0% 1008.0 ± 0% -3.08% (p=0.000 n=10) SpanWithEvents_4/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/AlwaysSample-12 1.641Ki ± 0% 1.609Ki ± 0% -1.90% (p=0.000 n=10) SpanWithEvents_8/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/AlwaysSample-12 624.0 ± 0% 592.0 ± 0% -5.13% (p=0.000 n=10) SpanWithEvents_WithStackTrace/NeverSample-12 160.0 ± 0% 160.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/AlwaysSample-12 648.0 ± 0% 616.0 ± 0% -4.94% (p=0.000 n=10) SpanWithEvents_WithTimestamp/NeverSample-12 184.0 ± 0% 184.0 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorVerboseLogging-12 9.547Ki ± 0% 9.234Ki ± 0% -3.27% (p=0.000 n=10) geomean ² -1.34% ² ¹ all samples are equal ² summaries must be >0 to compute geomean │ private/base2.txt │ private/new2.txt │ │ allocs/op │ allocs/op vs base │ Truncate/Unlimited-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Zero-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Short-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ASCII-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ValidUTF-8-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/InvalidUTF-8-12 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/MixedUTF-8-12 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/false-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/true-12 10.00 ± 0% 10.00 ± 0% ~ (p=1.000 n=10) ¹ SpanEnd-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_a_simple_span-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_several_links-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_attributes-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributeValueLengthLimit-12 41.00 ± 0% 41.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributeCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/EventCountLimit-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/LinkCountLimit-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributePerEventCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributePerLinkCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanSetAttributesOverCapacity-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ StartEndSpan/AlwaysSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ StartEndSpan/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/AlwaysSample-12 5.000 ± 0% 5.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/AlwaysSample-12 6.000 ± 0% 6.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/AlwaysSample-12 5.000 ± 0% 5.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/NeverSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorVerboseLogging-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ geomean ² +0.00% ² ¹ all samples are equal ² summaries must be >0 to compute geomean ``` See open-telemetry#6721.
Instead of using a mutex, use atomic compare-and-swap to set the endTime. Store unix nanoseconds as an int64 to enable atomics. This has few nice properties: - Span.End() no longer needs the mutex. The first call to Span.End() does an atomic compare-and-swap. Later calls will return early. - We remove the isRecording method and use the public IsRecording method since we don't need the mutex to access endTime. - We reduce the recordingSpan size by 32 bytes. time.Time takes 24 bytes compared to 8 bytes for int64 nanoseconds. We save 16 bytes each for startTime and endTime. Benchstat ``` benchstat private/base2.txt private/new2.txt goos: darwin goarch: arm64 pkg: go.opentelemetry.io/otel/sdk/trace cpu: Apple M2 Max │ private/base2.txt │ private/new2.txt │ │ sec/op │ sec/op vs base │ Truncate/Unlimited-12 0.2089n ± 2% 0.2090n ± 4% ~ (p=0.698 n=10) Truncate/Zero-12 0.3052n ± 1% 0.3087n ± 20% ~ (p=0.127 n=10) Truncate/Short-12 0.2081n ± 0% 0.2089n ± 1% ~ (p=0.362 n=10) Truncate/ASCII-12 0.7140n ± 2% 0.6855n ± 0% -4.00% (p=0.000 n=10) Truncate/ValidUTF-8-12 1.311n ± 2% 1.303n ± 1% -0.61% (p=0.015 n=10) Truncate/InvalidUTF-8-12 9.437n ± 1% 9.315n ± 3% ~ (p=0.143 n=10) Truncate/MixedUTF-8-12 17.32n ± 0% 17.16n ± 2% ~ (p=0.159 n=10) RecordingSpanSetAttributes/WithLimit/false-12 2.080µ ± 1% 2.010µ ± 1% -3.39% (p=0.000 n=10) RecordingSpanSetAttributes/WithLimit/true-12 4.358µ ± 0% 4.297µ ± 0% -1.40% (p=0.000 n=10) SpanEnd-12 107.90n ± 10% 94.44n ± 1% -12.47% (p=0.001 n=10) TraceStart/with_a_simple_span-12 319.5n ± 6% 293.7n ± 3% -8.08% (p=0.000 n=10) TraceStart/with_several_links-12 428.3n ± 2% 411.2n ± 1% -3.99% (p=0.000 n=10) TraceStart/with_attributes-12 469.6n ± 3% 430.4n ± 1% -8.35% (p=0.000 n=10) SpanLimits/AttributeValueLengthLimit-12 4.379µ ± 1% 4.144µ ± 1% -5.38% (p=0.000 n=10) SpanLimits/AttributeCountLimit-12 4.219µ ± 2% 3.909µ ± 1% -7.36% (p=0.000 n=10) SpanLimits/EventCountLimit-12 3.994µ ± 6% 3.663µ ± 1% -8.28% (p=0.000 n=10) SpanLimits/LinkCountLimit-12 3.835µ ± 2% 3.619µ ± 1% -5.63% (p=0.000 n=10) SpanLimits/AttributePerEventCountLimit-12 4.225µ ± 3% 3.961µ ± 1% -6.25% (p=0.000 n=10) SpanLimits/AttributePerLinkCountLimit-12 4.218µ ± 1% 3.951µ ± 1% -6.32% (p=0.000 n=10) SpanSetAttributesOverCapacity-12 1.676µ ± 2% 1.582µ ± 0% -5.58% (p=0.000 n=10) StartEndSpan/AlwaysSample-12 322.3n ± 0% 279.1n ± 0% -13.40% (p=0.000 n=10) StartEndSpan/NeverSample-12 153.5n ± 4% 148.1n ± 0% -3.55% (p=0.000 n=10) SpanWithAttributes_4/AlwaysSample-12 527.6n ± 1% 467.7n ± 0% -11.36% (p=0.000 n=10) SpanWithAttributes_4/NeverSample-12 245.1n ± 0% 227.6n ± 0% -7.14% (p=0.000 n=10) SpanWithAttributes_8/AlwaysSample-12 702.7n ± 2% 638.2n ± 1% -9.19% (p=0.000 n=10) SpanWithAttributes_8/NeverSample-12 336.4n ± 1% 305.0n ± 1% -9.32% (p=0.000 n=10) SpanWithAttributes_all/AlwaysSample-12 593.9n ± 3% 518.8n ± 1% -12.65% (p=0.000 n=10) SpanWithAttributes_all/NeverSample-12 267.0n ± 3% 251.6n ± 0% -5.73% (p=0.000 n=10) SpanWithAttributes_all_2x/AlwaysSample-12 850.2n ± 1% 749.9n ± 0% -11.80% (p=0.000 n=10) SpanWithAttributes_all_2x/NeverSample-12 398.4n ± 2% 350.8n ± 2% -11.95% (p=0.000 n=10) SpanWithEvents_4/AlwaysSample-12 736.3n ± 9% 640.9n ± 0% -12.96% (p=0.000 n=10) SpanWithEvents_4/NeverSample-12 158.1n ± 3% 149.8n ± 0% -5.25% (p=0.000 n=10) SpanWithEvents_8/AlwaysSample-12 1111.5n ± 1% 995.0n ± 0% -10.48% (p=0.000 n=10) SpanWithEvents_8/NeverSample-12 159.9n ± 2% 153.1n ± 0% -4.28% (p=0.000 n=10) SpanWithEvents_WithStackTrace/AlwaysSample-12 446.3n ± 1% 395.8n ± 0% -11.30% (p=0.000 n=10) SpanWithEvents_WithStackTrace/NeverSample-12 170.4n ± 1% 161.4n ± 0% -5.25% (p=0.000 n=10) SpanWithEvents_WithTimestamp/AlwaysSample-12 441.9n ± 1% 379.1n ± 0% -14.19% (p=0.000 n=10) SpanWithEvents_WithTimestamp/NeverSample-12 196.3n ± 5% 185.2n ± 1% -5.65% (p=0.000 n=10) TraceID_DotString-12 43.07n ± 1% 40.19n ± 0% -6.69% (p=0.000 n=10) SpanID_DotString-12 31.61n ± 1% 32.63n ± 0% +3.23% (p=0.001 n=10) SpanProcessorOnEnd/batch:_10,_spans:_10-12 163.3n ± 3% 162.3n ± 0% -0.64% (p=0.010 n=10) SpanProcessorOnEnd/batch:_10,_spans:_100-12 1.645µ ± 1% 1.624µ ± 0% -1.31% (p=0.000 n=10) SpanProcessorOnEnd/batch:_100,_spans:_10-12 162.2n ± 1% 162.5n ± 0% ~ (p=0.587 n=10) SpanProcessorOnEnd/batch:_100,_spans:_100-12 1.626µ ± 1% 1.623µ ± 0% ~ (p=0.361 n=10) SpanProcessorVerboseLogging-12 6.795µ ± 2% 5.789µ ± 3% -14.81% (p=0.000 n=10) geomean 225.5n 211.6n -6.19% │ private/base2.txt │ private/new2.txt │ │ B/op │ B/op vs base │ Truncate/Unlimited-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Zero-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Short-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ASCII-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ValidUTF-8-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/InvalidUTF-8-12 16.00 ± 0% 16.00 ± 0% ~ (p=1.000 n=10) ¹ Truncate/MixedUTF-8-12 32.00 ± 0% 32.00 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/false-12 6.891Ki ± 0% 6.859Ki ± 0% -0.45% (p=0.000 n=10) RecordingSpanSetAttributes/WithLimit/true-12 7.023Ki ± 0% 6.992Ki ± 0% -0.44% (p=0.000 n=10) SpanEnd-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_a_simple_span-12 528.0 ± 0% 496.0 ± 0% -6.06% (p=0.000 n=10) TraceStart/with_several_links-12 704.0 ± 0% 672.0 ± 0% -4.55% (p=0.000 n=10) TraceStart/with_attributes-12 784.0 ± 0% 752.0 ± 0% -4.08% (p=0.000 n=10) SpanLimits/AttributeValueLengthLimit-12 10.56Ki ± 0% 10.53Ki ± 0% -0.30% (p=0.000 n=10) SpanLimits/AttributeCountLimit-12 9.844Ki ± 0% 9.812Ki ± 0% -0.32% (p=0.000 n=10) SpanLimits/EventCountLimit-12 9.422Ki ± 0% 9.391Ki ± 0% -0.33% (p=0.000 n=10) SpanLimits/LinkCountLimit-12 9.031Ki ± 0% 9.000Ki ± 0% -0.35% (p=0.000 n=10) SpanLimits/AttributePerEventCountLimit-12 10.47Ki ± 0% 10.44Ki ± 0% -0.30% (p=0.000 n=10) SpanLimits/AttributePerLinkCountLimit-12 10.47Ki ± 0% 10.44Ki ± 0% -0.30% (p=0.000 n=10) SpanSetAttributesOverCapacity-12 592.0 ± 0% 560.0 ± 0% -5.41% (p=0.000 n=10) StartEndSpan/AlwaysSample-12 528.0 ± 0% 496.0 ± 0% -6.06% (p=0.000 n=10) StartEndSpan/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/AlwaysSample-12 1040.0 ± 0% 1008.0 ± 0% -3.08% (p=0.000 n=10) SpanWithAttributes_4/NeverSample-12 400.0 ± 0% 400.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/AlwaysSample-12 1.516Ki ± 0% 1.484Ki ± 0% -2.06% (p=0.000 n=10) SpanWithAttributes_8/NeverSample-12 656.0 ± 0% 656.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/AlwaysSample-12 1.141Ki ± 0% 1.109Ki ± 0% -2.74% (p=0.000 n=10) SpanWithAttributes_all/NeverSample-12 464.0 ± 0% 464.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/AlwaysSample-12 1.891Ki ± 0% 1.859Ki ± 0% -1.65% (p=0.000 n=10) SpanWithAttributes_all_2x/NeverSample-12 848.0 ± 0% 848.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/AlwaysSample-12 1040.0 ± 0% 1008.0 ± 0% -3.08% (p=0.000 n=10) SpanWithEvents_4/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/AlwaysSample-12 1.641Ki ± 0% 1.609Ki ± 0% -1.90% (p=0.000 n=10) SpanWithEvents_8/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/AlwaysSample-12 624.0 ± 0% 592.0 ± 0% -5.13% (p=0.000 n=10) SpanWithEvents_WithStackTrace/NeverSample-12 160.0 ± 0% 160.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/AlwaysSample-12 648.0 ± 0% 616.0 ± 0% -4.94% (p=0.000 n=10) SpanWithEvents_WithTimestamp/NeverSample-12 184.0 ± 0% 184.0 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorVerboseLogging-12 9.547Ki ± 0% 9.234Ki ± 0% -3.27% (p=0.000 n=10) geomean ² -1.34% ² ¹ all samples are equal ² summaries must be >0 to compute geomean │ private/base2.txt │ private/new2.txt │ │ allocs/op │ allocs/op vs base │ Truncate/Unlimited-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Zero-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Short-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ASCII-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ValidUTF-8-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/InvalidUTF-8-12 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/MixedUTF-8-12 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/false-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/true-12 10.00 ± 0% 10.00 ± 0% ~ (p=1.000 n=10) ¹ SpanEnd-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_a_simple_span-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_several_links-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_attributes-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributeValueLengthLimit-12 41.00 ± 0% 41.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributeCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/EventCountLimit-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/LinkCountLimit-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributePerEventCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributePerLinkCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanSetAttributesOverCapacity-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ StartEndSpan/AlwaysSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ StartEndSpan/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/AlwaysSample-12 5.000 ± 0% 5.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/AlwaysSample-12 6.000 ± 0% 6.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/AlwaysSample-12 5.000 ± 0% 5.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/NeverSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorVerboseLogging-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ geomean ² +0.00% ² ¹ all samples are equal ² summaries must be >0 to compute geomean ``` See open-telemetry#6721.
@jschaf, why has this issue been closed? |
I figured the cost-benefit wasn't worth it. @dmathieu said the absolute speedup of the atomics PR was small—the other optimizations are even smaller. I'm happy to reopen if y'all are interested. I've already implemented them in my experimental code, so it's not a big lift. |
I think looking at your other proposals would be nice. |
With specialized routines, we can avoid the allocation of hex.DecodeString since we know the structure of the IDs. We can use `==` instead of bytes.Equal for arrays. From the Go [spec]: > Array types are comparable if their array element types are comparable. Two > array values are equal if their corresponding element values are equal. The > elements are compared in ascending index order, and comparison stops as soon > as two element values differ (or all elements have been compared). [spec]: https://go.dev/ref/spec#Comparison_operators Issue: open-telemetry#6721
With specialized routines, we can avoid the allocation of hex.DecodeString since we know the structure of the IDs. We can use `==` instead of bytes.Equal for arrays. From the Go [spec]: > Array types are comparable if their array element types are comparable. Two > array values are equal if their corresponding element values are equal. The > elements are compared in ascending index order, and comparison stops as soon > as two element values differ (or all elements have been compared). [spec]: https://go.dev/ref/spec#Comparison_operators ### Benchstat To generate: ```sh mkdir private cd sdk go test -run=xxxxMatchNothingxxxx -bench=. -count=10 go.opentelemetry.io/otel/sdk/trace -timeout=30m | tee ../private/base.txt go test -run=xxxxMatchNothingxxxx -bench=. -count=10 go.opentelemetry.io/otel/sdk/trace -timeout=30m | tee ../private/new.txt benchstat ../private/base.txt ../private/new.txt ``` Results: ``` goos: darwin goarch: arm64 pkg: go.opentelemetry.io/otel/sdk/trace cpu: Apple M2 Max │ ../private/base.txt │ ../private/new1.txt │ │ sec/op │ sec/op vs base │ Truncate/Unlimited-12 0.2086n ± 1% 0.2140n ± 3% +2.59% (p=0.017 n=10) Truncate/Zero-12 0.3048n ± 0% 0.3070n ± 1% +0.71% (p=0.014 n=10) Truncate/Short-12 0.2083n ± 2% 0.2097n ± 1% ~ (p=0.148 n=10) Truncate/ASCII-12 0.6870n ± 0% 0.6855n ± 0% ~ (p=0.493 n=10) Truncate/ValidUTF-8-12 1.298n ± 0% 1.302n ± 1% +0.31% (p=0.003 n=10) Truncate/InvalidUTF-8-12 9.457n ± 0% 9.420n ± 1% ~ (p=0.529 n=10) Truncate/MixedUTF-8-12 17.30n ± 1% 17.29n ± 0% ~ (p=0.359 n=10) RecordingSpanSetAttributes/WithLimit/false-12 2.055µ ± 1% 2.082µ ± 9% +1.29% (p=0.014 n=10) RecordingSpanSetAttributes/WithLimit/true-12 4.368µ ± 0% 4.364µ ± 0% -0.08% (p=0.049 n=10) SpanEnd-12 72.57n ± 17% 73.75n ± 16% ~ (p=0.853 n=10) TraceStart/with_a_simple_span-12 320.1n ± 10% 314.6n ± 10% ~ (p=0.165 n=10) TraceStart/with_several_links-12 432.7n ± 2% 429.4n ± 1% ~ (p=0.063 n=10) TraceStart/with_attributes-12 477.3n ± 1% 468.1n ± 6% -1.94% (p=0.005 n=10) SpanLimits/AttributeValueLengthLimit-12 4.401µ ± 1% 4.439µ ± 2% ~ (p=0.089 n=10) SpanLimits/AttributeCountLimit-12 4.125µ ± 1% 4.151µ ± 1% +0.62% (p=0.014 n=10) SpanLimits/EventCountLimit-12 3.900µ ± 2% 3.935µ ± 1% +0.88% (p=0.023 n=10) SpanLimits/LinkCountLimit-12 3.870µ ± 2% 3.901µ ± 1% ~ (p=0.148 n=10) SpanLimits/AttributePerEventCountLimit-12 4.212µ ± 1% 4.243µ ± 1% +0.75% (p=0.008 n=10) SpanLimits/AttributePerLinkCountLimit-12 4.200µ ± 1% 4.224µ ± 0% +0.57% (p=0.041 n=10) SpanSetAttributesOverCapacity-12 1.661µ ± 1% 1.653µ ± 0% -0.48% (p=0.049 n=10) StartEndSpan/AlwaysSample-12 317.9n ± 0% 316.5n ± 0% -0.44% (p=0.007 n=10) StartEndSpan/NeverSample-12 152.3n ± 0% 152.0n ± 0% -0.23% (p=0.005 n=10) SpanWithAttributes_4/AlwaysSample-12 527.2n ± 0% 532.4n ± 1% +1.00% (p=0.000 n=10) SpanWithAttributes_4/NeverSample-12 240.6n ± 0% 241.6n ± 0% +0.46% (p=0.000 n=10) SpanWithAttributes_8/AlwaysSample-12 704.5n ± 0% 718.3n ± 1% +1.97% (p=0.000 n=10) SpanWithAttributes_8/NeverSample-12 325.0n ± 0% 327.2n ± 1% +0.68% (p=0.000 n=10) SpanWithAttributes_all/AlwaysSample-12 576.8n ± 0% 584.7n ± 1% +1.37% (p=0.000 n=10) SpanWithAttributes_all/NeverSample-12 264.6n ± 1% 263.3n ± 0% -0.47% (p=0.045 n=10) SpanWithAttributes_all_2x/AlwaysSample-12 818.6n ± 1% 834.9n ± 0% +1.98% (p=0.000 n=10) SpanWithAttributes_all_2x/NeverSample-12 378.3n ± 0% 382.9n ± 1% +1.23% (p=0.000 n=10) SpanWithEvents_4/AlwaysSample-12 715.1n ± 1% 721.1n ± 0% +0.83% (p=0.003 n=10) SpanWithEvents_4/NeverSample-12 156.1n ± 1% 155.1n ± 1% -0.64% (p=0.002 n=10) SpanWithEvents_8/AlwaysSample-12 1.098µ ± 0% 1.104µ ± 0% +0.55% (p=0.000 n=10) SpanWithEvents_8/NeverSample-12 158.8n ± 0% 158.6n ± 1% ~ (p=0.288 n=10) SpanWithEvents_WithStackTrace/AlwaysSample-12 438.8n ± 0% 438.5n ± 0% ~ (p=0.868 n=10) SpanWithEvents_WithStackTrace/NeverSample-12 168.2n ± 1% 167.4n ± 1% -0.48% (p=0.014 n=10) SpanWithEvents_WithTimestamp/AlwaysSample-12 430.6n ± 0% 432.9n ± 0% +0.53% (p=0.001 n=10) SpanWithEvents_WithTimestamp/NeverSample-12 193.7n ± 0% 190.1n ± 1% -1.91% (p=0.000 n=10) TraceID_DotString-12 42.37n ± 0% 24.80n ± 0% -41.45% (p=0.000 n=10) SpanID_DotString-12 31.30n ± 0% 17.22n ± 0% -44.98% (p=0.000 n=10) SpanProcessorOnEnd/batch:_10,_spans:_10-12 163.3n ± 0% 163.4n ± 0% ~ (p=0.120 n=10) SpanProcessorOnEnd/batch:_10,_spans:_100-12 1.639µ ± 0% 1.635µ ± 0% -0.27% (p=0.000 n=10) SpanProcessorOnEnd/batch:_100,_spans:_10-12 163.3n ± 0% 163.2n ± 0% ~ (p=0.115 n=10) SpanProcessorOnEnd/batch:_100,_spans:_100-12 1.636µ ± 0% 1.635µ ± 1% ~ (p=0.509 n=10) SpanProcessorVerboseLogging-12 6.769µ ± 2% 6.600µ ± 2% -2.49% (p=0.030 n=10) geomean 221.4n 216.4n -2.29% │ ../private/base.txt │ ../private/new1.txt │ │ B/op │ B/op vs base │ Truncate/Unlimited-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Zero-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Short-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ASCII-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ValidUTF-8-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/InvalidUTF-8-12 16.00 ± 0% 16.00 ± 0% ~ (p=1.000 n=10) ¹ Truncate/MixedUTF-8-12 32.00 ± 0% 32.00 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/false-12 6.891Ki ± 0% 6.891Ki ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/true-12 7.023Ki ± 0% 7.023Ki ± 0% ~ (p=1.000 n=10) ¹ SpanEnd-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_a_simple_span-12 528.0 ± 0% 528.0 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_several_links-12 704.0 ± 0% 704.0 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_attributes-12 784.0 ± 0% 784.0 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributeValueLengthLimit-12 10.56Ki ± 0% 10.56Ki ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributeCountLimit-12 9.844Ki ± 0% 9.844Ki ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/EventCountLimit-12 9.422Ki ± 0% 9.422Ki ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/LinkCountLimit-12 9.031Ki ± 0% 9.031Ki ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributePerEventCountLimit-12 10.47Ki ± 0% 10.47Ki ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributePerLinkCountLimit-12 10.47Ki ± 0% 10.47Ki ± 0% ~ (p=1.000 n=10) ¹ SpanSetAttributesOverCapacity-12 592.0 ± 0% 592.0 ± 0% ~ (p=1.000 n=10) ¹ StartEndSpan/AlwaysSample-12 528.0 ± 0% 528.0 ± 0% ~ (p=1.000 n=10) ¹ StartEndSpan/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/AlwaysSample-12 1.016Ki ± 0% 1.016Ki ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/NeverSample-12 400.0 ± 0% 400.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/AlwaysSample-12 1.516Ki ± 0% 1.516Ki ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/NeverSample-12 656.0 ± 0% 656.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/AlwaysSample-12 1.141Ki ± 0% 1.141Ki ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/NeverSample-12 464.0 ± 0% 464.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/AlwaysSample-12 1.891Ki ± 0% 1.891Ki ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/NeverSample-12 848.0 ± 0% 848.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/AlwaysSample-12 1.016Ki ± 0% 1.016Ki ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/AlwaysSample-12 1.641Ki ± 0% 1.641Ki ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/AlwaysSample-12 624.0 ± 0% 624.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/NeverSample-12 160.0 ± 0% 160.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/AlwaysSample-12 648.0 ± 0% 648.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/NeverSample-12 184.0 ± 0% 184.0 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorVerboseLogging-12 9.547Ki ± 0% 9.547Ki ± 0% ~ (p=1.000 n=10) ¹ geomean ² +0.00% ² ¹ all samples are equal ² summaries must be >0 to compute geomean │ ../private/base.txt │ ../private/new1.txt │ │ allocs/op │ allocs/op vs base │ Truncate/Unlimited-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Zero-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Short-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ASCII-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ValidUTF-8-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/InvalidUTF-8-12 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/MixedUTF-8-12 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/false-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/true-12 10.00 ± 0% 10.00 ± 0% ~ (p=1.000 n=10) ¹ SpanEnd-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_a_simple_span-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_several_links-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_attributes-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributeValueLengthLimit-12 41.00 ± 0% 41.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributeCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/EventCountLimit-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/LinkCountLimit-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributePerEventCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributePerLinkCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanSetAttributesOverCapacity-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ StartEndSpan/AlwaysSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ StartEndSpan/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/AlwaysSample-12 5.000 ± 0% 5.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/AlwaysSample-12 6.000 ± 0% 6.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/AlwaysSample-12 5.000 ± 0% 5.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/NeverSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorVerboseLogging-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ geomean ² +0.00% ² ¹ all samples are equal ² summaries must be >0 to compute geomean ``` Issue: open-telemetry#6721
With specialized routines, we can avoid the allocation of hex.DecodeString since we know the structure of the IDs. We can use `==` instead of bytes.Equal for arrays. From the Go [spec]: > Array types are comparable if their array element types are comparable. Two > array values are equal if their corresponding element values are equal. The > elements are compared in ascending index order, and comparison stops as soon > as two element values differ (or all elements have been compared). [spec]: https://go.dev/ref/spec#Comparison_operators ### Benchstat To generate: ```sh mkdir private cd sdk go test -run=xxxxMatchNothingxxxx -bench=. -count=10 go.opentelemetry.io/otel/sdk/trace -timeout=30m | tee ../private/base.txt go test -run=xxxxMatchNothingxxxx -bench=. -count=10 go.opentelemetry.io/otel/sdk/trace -timeout=30m | tee ../private/new.txt benchstat ../private/base.txt ../private/new.txt ``` Results: ``` goos: darwin goarch: arm64 pkg: go.opentelemetry.io/otel/sdk/trace cpu: Apple M2 Max │ ../private/base.txt │ ../private/new.txt │ │ sec/op │ sec/op vs base │ Truncate/Unlimited-12 0.2086n ± 1% 0.2140n ± 3% +2.59% (p=0.017 n=10) Truncate/Zero-12 0.3048n ± 0% 0.3070n ± 1% +0.71% (p=0.014 n=10) Truncate/Short-12 0.2083n ± 2% 0.2097n ± 1% ~ (p=0.148 n=10) Truncate/ASCII-12 0.6870n ± 0% 0.6855n ± 0% ~ (p=0.493 n=10) Truncate/ValidUTF-8-12 1.298n ± 0% 1.302n ± 1% +0.31% (p=0.003 n=10) Truncate/InvalidUTF-8-12 9.457n ± 0% 9.420n ± 1% ~ (p=0.529 n=10) Truncate/MixedUTF-8-12 17.30n ± 1% 17.29n ± 0% ~ (p=0.359 n=10) RecordingSpanSetAttributes/WithLimit/false-12 2.055µ ± 1% 2.082µ ± 9% +1.29% (p=0.014 n=10) RecordingSpanSetAttributes/WithLimit/true-12 4.368µ ± 0% 4.364µ ± 0% -0.08% (p=0.049 n=10) SpanEnd-12 72.57n ± 17% 73.75n ± 16% ~ (p=0.853 n=10) TraceStart/with_a_simple_span-12 320.1n ± 10% 314.6n ± 10% ~ (p=0.165 n=10) TraceStart/with_several_links-12 432.7n ± 2% 429.4n ± 1% ~ (p=0.063 n=10) TraceStart/with_attributes-12 477.3n ± 1% 468.1n ± 6% -1.94% (p=0.005 n=10) SpanLimits/AttributeValueLengthLimit-12 4.401µ ± 1% 4.439µ ± 2% ~ (p=0.089 n=10) SpanLimits/AttributeCountLimit-12 4.125µ ± 1% 4.151µ ± 1% +0.62% (p=0.014 n=10) SpanLimits/EventCountLimit-12 3.900µ ± 2% 3.935µ ± 1% +0.88% (p=0.023 n=10) SpanLimits/LinkCountLimit-12 3.870µ ± 2% 3.901µ ± 1% ~ (p=0.148 n=10) SpanLimits/AttributePerEventCountLimit-12 4.212µ ± 1% 4.243µ ± 1% +0.75% (p=0.008 n=10) SpanLimits/AttributePerLinkCountLimit-12 4.200µ ± 1% 4.224µ ± 0% +0.57% (p=0.041 n=10) SpanSetAttributesOverCapacity-12 1.661µ ± 1% 1.653µ ± 0% -0.48% (p=0.049 n=10) StartEndSpan/AlwaysSample-12 317.9n ± 0% 316.5n ± 0% -0.44% (p=0.007 n=10) StartEndSpan/NeverSample-12 152.3n ± 0% 152.0n ± 0% -0.23% (p=0.005 n=10) SpanWithAttributes_4/AlwaysSample-12 527.2n ± 0% 532.4n ± 1% +1.00% (p=0.000 n=10) SpanWithAttributes_4/NeverSample-12 240.6n ± 0% 241.6n ± 0% +0.46% (p=0.000 n=10) SpanWithAttributes_8/AlwaysSample-12 704.5n ± 0% 718.3n ± 1% +1.97% (p=0.000 n=10) SpanWithAttributes_8/NeverSample-12 325.0n ± 0% 327.2n ± 1% +0.68% (p=0.000 n=10) SpanWithAttributes_all/AlwaysSample-12 576.8n ± 0% 584.7n ± 1% +1.37% (p=0.000 n=10) SpanWithAttributes_all/NeverSample-12 264.6n ± 1% 263.3n ± 0% -0.47% (p=0.045 n=10) SpanWithAttributes_all_2x/AlwaysSample-12 818.6n ± 1% 834.9n ± 0% +1.98% (p=0.000 n=10) SpanWithAttributes_all_2x/NeverSample-12 378.3n ± 0% 382.9n ± 1% +1.23% (p=0.000 n=10) SpanWithEvents_4/AlwaysSample-12 715.1n ± 1% 721.1n ± 0% +0.83% (p=0.003 n=10) SpanWithEvents_4/NeverSample-12 156.1n ± 1% 155.1n ± 1% -0.64% (p=0.002 n=10) SpanWithEvents_8/AlwaysSample-12 1.098µ ± 0% 1.104µ ± 0% +0.55% (p=0.000 n=10) SpanWithEvents_8/NeverSample-12 158.8n ± 0% 158.6n ± 1% ~ (p=0.288 n=10) SpanWithEvents_WithStackTrace/AlwaysSample-12 438.8n ± 0% 438.5n ± 0% ~ (p=0.868 n=10) SpanWithEvents_WithStackTrace/NeverSample-12 168.2n ± 1% 167.4n ± 1% -0.48% (p=0.014 n=10) SpanWithEvents_WithTimestamp/AlwaysSample-12 430.6n ± 0% 432.9n ± 0% +0.53% (p=0.001 n=10) SpanWithEvents_WithTimestamp/NeverSample-12 193.7n ± 0% 190.1n ± 1% -1.91% (p=0.000 n=10) TraceID_DotString-12 42.37n ± 0% 24.80n ± 0% -41.45% (p=0.000 n=10) SpanID_DotString-12 31.30n ± 0% 17.22n ± 0% -44.98% (p=0.000 n=10) SpanProcessorOnEnd/batch:_10,_spans:_10-12 163.3n ± 0% 163.4n ± 0% ~ (p=0.120 n=10) SpanProcessorOnEnd/batch:_10,_spans:_100-12 1.639µ ± 0% 1.635µ ± 0% -0.27% (p=0.000 n=10) SpanProcessorOnEnd/batch:_100,_spans:_10-12 163.3n ± 0% 163.2n ± 0% ~ (p=0.115 n=10) SpanProcessorOnEnd/batch:_100,_spans:_100-12 1.636µ ± 0% 1.635µ ± 1% ~ (p=0.509 n=10) SpanProcessorVerboseLogging-12 6.769µ ± 2% 6.600µ ± 2% -2.49% (p=0.030 n=10) geomean 221.4n 216.4n -2.29% │ ../private/base.txt │ ../private/new.txt │ │ B/op │ B/op vs base │ Truncate/Unlimited-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Zero-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Short-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ASCII-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ValidUTF-8-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/InvalidUTF-8-12 16.00 ± 0% 16.00 ± 0% ~ (p=1.000 n=10) ¹ Truncate/MixedUTF-8-12 32.00 ± 0% 32.00 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/false-12 6.891Ki ± 0% 6.891Ki ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/true-12 7.023Ki ± 0% 7.023Ki ± 0% ~ (p=1.000 n=10) ¹ SpanEnd-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_a_simple_span-12 528.0 ± 0% 528.0 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_several_links-12 704.0 ± 0% 704.0 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_attributes-12 784.0 ± 0% 784.0 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributeValueLengthLimit-12 10.56Ki ± 0% 10.56Ki ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributeCountLimit-12 9.844Ki ± 0% 9.844Ki ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/EventCountLimit-12 9.422Ki ± 0% 9.422Ki ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/LinkCountLimit-12 9.031Ki ± 0% 9.031Ki ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributePerEventCountLimit-12 10.47Ki ± 0% 10.47Ki ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributePerLinkCountLimit-12 10.47Ki ± 0% 10.47Ki ± 0% ~ (p=1.000 n=10) ¹ SpanSetAttributesOverCapacity-12 592.0 ± 0% 592.0 ± 0% ~ (p=1.000 n=10) ¹ StartEndSpan/AlwaysSample-12 528.0 ± 0% 528.0 ± 0% ~ (p=1.000 n=10) ¹ StartEndSpan/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/AlwaysSample-12 1.016Ki ± 0% 1.016Ki ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/NeverSample-12 400.0 ± 0% 400.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/AlwaysSample-12 1.516Ki ± 0% 1.516Ki ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/NeverSample-12 656.0 ± 0% 656.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/AlwaysSample-12 1.141Ki ± 0% 1.141Ki ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/NeverSample-12 464.0 ± 0% 464.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/AlwaysSample-12 1.891Ki ± 0% 1.891Ki ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/NeverSample-12 848.0 ± 0% 848.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/AlwaysSample-12 1.016Ki ± 0% 1.016Ki ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/AlwaysSample-12 1.641Ki ± 0% 1.641Ki ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/AlwaysSample-12 624.0 ± 0% 624.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/NeverSample-12 160.0 ± 0% 160.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/AlwaysSample-12 648.0 ± 0% 648.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/NeverSample-12 184.0 ± 0% 184.0 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorVerboseLogging-12 9.547Ki ± 0% 9.547Ki ± 0% ~ (p=1.000 n=10) ¹ geomean ² +0.00% ² ¹ all samples are equal ² summaries must be >0 to compute geomean │ ../private/base.txt │ ../private/new.txt │ │ allocs/op │ allocs/op vs base │ Truncate/Unlimited-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Zero-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Short-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ASCII-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ValidUTF-8-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/InvalidUTF-8-12 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/MixedUTF-8-12 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/false-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/true-12 10.00 ± 0% 10.00 ± 0% ~ (p=1.000 n=10) ¹ SpanEnd-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_a_simple_span-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_several_links-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_attributes-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributeValueLengthLimit-12 41.00 ± 0% 41.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributeCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/EventCountLimit-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/LinkCountLimit-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributePerEventCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributePerLinkCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanSetAttributesOverCapacity-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ StartEndSpan/AlwaysSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ StartEndSpan/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/AlwaysSample-12 5.000 ± 0% 5.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/AlwaysSample-12 6.000 ± 0% 6.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/AlwaysSample-12 5.000 ± 0% 5.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/NeverSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorVerboseLogging-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ geomean ² +0.00% ² ¹ all samples are equal ² summaries must be >0 to compute geomean ``` Issue: open-telemetry#6721
With specialized routines, we can avoid the allocation of hex.DecodeString since we know the structure of the IDs. We can use `==` instead of bytes.Equal for arrays. From the Go [spec]: > Array types are comparable if their array element types are comparable. Two > array values are equal if their corresponding element values are equal. The > elements are compared in ascending index order, and comparison stops as soon > as two element values differ (or all elements have been compared). [spec]: https://go.dev/ref/spec#Comparison_operators ### Benchstat To generate: ```sh mkdir private cd sdk go test -run=xxxxMatchNothingxxxx -bench=. -count=10 go.opentelemetry.io/otel/sdk/trace -timeout=30m | tee ../private/base.txt go test -run=xxxxMatchNothingxxxx -bench=. -count=10 go.opentelemetry.io/otel/sdk/trace -timeout=30m | tee ../private/new.txt benchstat ../private/base.txt ../private/new.txt ``` Results: ``` goos: darwin goarch: arm64 pkg: go.opentelemetry.io/otel/sdk/trace cpu: Apple M2 Max │ ../private/base.txt │ ../private/new.txt │ │ sec/op │ sec/op vs base │ Truncate/Unlimited-12 0.2086n ± 1% 0.2140n ± 3% +2.59% (p=0.017 n=10) Truncate/Zero-12 0.3048n ± 0% 0.3070n ± 1% +0.71% (p=0.014 n=10) Truncate/Short-12 0.2083n ± 2% 0.2097n ± 1% ~ (p=0.148 n=10) Truncate/ASCII-12 0.6870n ± 0% 0.6855n ± 0% ~ (p=0.493 n=10) Truncate/ValidUTF-8-12 1.298n ± 0% 1.302n ± 1% +0.31% (p=0.003 n=10) Truncate/InvalidUTF-8-12 9.457n ± 0% 9.420n ± 1% ~ (p=0.529 n=10) Truncate/MixedUTF-8-12 17.30n ± 1% 17.29n ± 0% ~ (p=0.359 n=10) RecordingSpanSetAttributes/WithLimit/false-12 2.055µ ± 1% 2.082µ ± 9% +1.29% (p=0.014 n=10) RecordingSpanSetAttributes/WithLimit/true-12 4.368µ ± 0% 4.364µ ± 0% -0.08% (p=0.049 n=10) SpanEnd-12 72.57n ± 17% 73.75n ± 16% ~ (p=0.853 n=10) TraceStart/with_a_simple_span-12 320.1n ± 10% 314.6n ± 10% ~ (p=0.165 n=10) TraceStart/with_several_links-12 432.7n ± 2% 429.4n ± 1% ~ (p=0.063 n=10) TraceStart/with_attributes-12 477.3n ± 1% 468.1n ± 6% -1.94% (p=0.005 n=10) SpanLimits/AttributeValueLengthLimit-12 4.401µ ± 1% 4.439µ ± 2% ~ (p=0.089 n=10) SpanLimits/AttributeCountLimit-12 4.125µ ± 1% 4.151µ ± 1% +0.62% (p=0.014 n=10) SpanLimits/EventCountLimit-12 3.900µ ± 2% 3.935µ ± 1% +0.88% (p=0.023 n=10) SpanLimits/LinkCountLimit-12 3.870µ ± 2% 3.901µ ± 1% ~ (p=0.148 n=10) SpanLimits/AttributePerEventCountLimit-12 4.212µ ± 1% 4.243µ ± 1% +0.75% (p=0.008 n=10) SpanLimits/AttributePerLinkCountLimit-12 4.200µ ± 1% 4.224µ ± 0% +0.57% (p=0.041 n=10) SpanSetAttributesOverCapacity-12 1.661µ ± 1% 1.653µ ± 0% -0.48% (p=0.049 n=10) StartEndSpan/AlwaysSample-12 317.9n ± 0% 316.5n ± 0% -0.44% (p=0.007 n=10) StartEndSpan/NeverSample-12 152.3n ± 0% 152.0n ± 0% -0.23% (p=0.005 n=10) SpanWithAttributes_4/AlwaysSample-12 527.2n ± 0% 532.4n ± 1% +1.00% (p=0.000 n=10) SpanWithAttributes_4/NeverSample-12 240.6n ± 0% 241.6n ± 0% +0.46% (p=0.000 n=10) SpanWithAttributes_8/AlwaysSample-12 704.5n ± 0% 718.3n ± 1% +1.97% (p=0.000 n=10) SpanWithAttributes_8/NeverSample-12 325.0n ± 0% 327.2n ± 1% +0.68% (p=0.000 n=10) SpanWithAttributes_all/AlwaysSample-12 576.8n ± 0% 584.7n ± 1% +1.37% (p=0.000 n=10) SpanWithAttributes_all/NeverSample-12 264.6n ± 1% 263.3n ± 0% -0.47% (p=0.045 n=10) SpanWithAttributes_all_2x/AlwaysSample-12 818.6n ± 1% 834.9n ± 0% +1.98% (p=0.000 n=10) SpanWithAttributes_all_2x/NeverSample-12 378.3n ± 0% 382.9n ± 1% +1.23% (p=0.000 n=10) SpanWithEvents_4/AlwaysSample-12 715.1n ± 1% 721.1n ± 0% +0.83% (p=0.003 n=10) SpanWithEvents_4/NeverSample-12 156.1n ± 1% 155.1n ± 1% -0.64% (p=0.002 n=10) SpanWithEvents_8/AlwaysSample-12 1.098µ ± 0% 1.104µ ± 0% +0.55% (p=0.000 n=10) SpanWithEvents_8/NeverSample-12 158.8n ± 0% 158.6n ± 1% ~ (p=0.288 n=10) SpanWithEvents_WithStackTrace/AlwaysSample-12 438.8n ± 0% 438.5n ± 0% ~ (p=0.868 n=10) SpanWithEvents_WithStackTrace/NeverSample-12 168.2n ± 1% 167.4n ± 1% -0.48% (p=0.014 n=10) SpanWithEvents_WithTimestamp/AlwaysSample-12 430.6n ± 0% 432.9n ± 0% +0.53% (p=0.001 n=10) SpanWithEvents_WithTimestamp/NeverSample-12 193.7n ± 0% 190.1n ± 1% -1.91% (p=0.000 n=10) TraceID_DotString-12 42.37n ± 0% 24.80n ± 0% -41.45% (p=0.000 n=10) SpanID_DotString-12 31.30n ± 0% 17.22n ± 0% -44.98% (p=0.000 n=10) SpanProcessorOnEnd/batch:_10,_spans:_10-12 163.3n ± 0% 163.4n ± 0% ~ (p=0.120 n=10) SpanProcessorOnEnd/batch:_10,_spans:_100-12 1.639µ ± 0% 1.635µ ± 0% -0.27% (p=0.000 n=10) SpanProcessorOnEnd/batch:_100,_spans:_10-12 163.3n ± 0% 163.2n ± 0% ~ (p=0.115 n=10) SpanProcessorOnEnd/batch:_100,_spans:_100-12 1.636µ ± 0% 1.635µ ± 1% ~ (p=0.509 n=10) SpanProcessorVerboseLogging-12 6.769µ ± 2% 6.600µ ± 2% -2.49% (p=0.030 n=10) geomean 221.4n 216.4n -2.29% │ ../private/base.txt │ ../private/new.txt │ │ B/op │ B/op vs base │ Truncate/Unlimited-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Zero-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Short-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ASCII-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ValidUTF-8-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/InvalidUTF-8-12 16.00 ± 0% 16.00 ± 0% ~ (p=1.000 n=10) ¹ Truncate/MixedUTF-8-12 32.00 ± 0% 32.00 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/false-12 6.891Ki ± 0% 6.891Ki ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/true-12 7.023Ki ± 0% 7.023Ki ± 0% ~ (p=1.000 n=10) ¹ SpanEnd-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_a_simple_span-12 528.0 ± 0% 528.0 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_several_links-12 704.0 ± 0% 704.0 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_attributes-12 784.0 ± 0% 784.0 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributeValueLengthLimit-12 10.56Ki ± 0% 10.56Ki ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributeCountLimit-12 9.844Ki ± 0% 9.844Ki ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/EventCountLimit-12 9.422Ki ± 0% 9.422Ki ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/LinkCountLimit-12 9.031Ki ± 0% 9.031Ki ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributePerEventCountLimit-12 10.47Ki ± 0% 10.47Ki ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributePerLinkCountLimit-12 10.47Ki ± 0% 10.47Ki ± 0% ~ (p=1.000 n=10) ¹ SpanSetAttributesOverCapacity-12 592.0 ± 0% 592.0 ± 0% ~ (p=1.000 n=10) ¹ StartEndSpan/AlwaysSample-12 528.0 ± 0% 528.0 ± 0% ~ (p=1.000 n=10) ¹ StartEndSpan/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/AlwaysSample-12 1.016Ki ± 0% 1.016Ki ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/NeverSample-12 400.0 ± 0% 400.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/AlwaysSample-12 1.516Ki ± 0% 1.516Ki ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/NeverSample-12 656.0 ± 0% 656.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/AlwaysSample-12 1.141Ki ± 0% 1.141Ki ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/NeverSample-12 464.0 ± 0% 464.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/AlwaysSample-12 1.891Ki ± 0% 1.891Ki ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/NeverSample-12 848.0 ± 0% 848.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/AlwaysSample-12 1.016Ki ± 0% 1.016Ki ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/AlwaysSample-12 1.641Ki ± 0% 1.641Ki ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/AlwaysSample-12 624.0 ± 0% 624.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/NeverSample-12 160.0 ± 0% 160.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/AlwaysSample-12 648.0 ± 0% 648.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/NeverSample-12 184.0 ± 0% 184.0 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorVerboseLogging-12 9.547Ki ± 0% 9.547Ki ± 0% ~ (p=1.000 n=10) ¹ geomean ² +0.00% ² ¹ all samples are equal ² summaries must be >0 to compute geomean │ ../private/base.txt │ ../private/new.txt │ │ allocs/op │ allocs/op vs base │ Truncate/Unlimited-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Zero-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Short-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ASCII-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ValidUTF-8-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/InvalidUTF-8-12 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/MixedUTF-8-12 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/false-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/true-12 10.00 ± 0% 10.00 ± 0% ~ (p=1.000 n=10) ¹ SpanEnd-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_a_simple_span-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_several_links-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_attributes-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributeValueLengthLimit-12 41.00 ± 0% 41.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributeCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/EventCountLimit-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/LinkCountLimit-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributePerEventCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributePerLinkCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanSetAttributesOverCapacity-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ StartEndSpan/AlwaysSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ StartEndSpan/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/AlwaysSample-12 5.000 ± 0% 5.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/AlwaysSample-12 6.000 ± 0% 6.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/AlwaysSample-12 5.000 ± 0% 5.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/NeverSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorVerboseLogging-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ geomean ² +0.00% ² ¹ all samples are equal ² summaries must be >0 to compute geomean ``` Issue: open-telemetry#6721
Sent #6791 for optimization 1: inline hex encoding and decoding. Speeds up the string method by 1.8x.
|
With specialized routines, we can avoid the allocation of hex.DecodeString since we know the structure of the IDs. We can use `==` instead of bytes.Equal for arrays. From the Go [spec]: > Array types are comparable if their array element types are comparable. Two > array values are equal if their corresponding element values are equal. The > elements are compared in ascending index order, and comparison stops as soon > as two element values differ (or all elements have been compared). [spec]: https://go.dev/ref/spec#Comparison_operators ### Benchstat To generate: ```sh mkdir private cd sdk go test -run=xxxxMatchNothingxxxx -bench=. -count=10 go.opentelemetry.io/otel/sdk/trace -timeout=30m | tee ../private/base.txt go test -run=xxxxMatchNothingxxxx -bench=. -count=10 go.opentelemetry.io/otel/sdk/trace -timeout=30m | tee ../private/new.txt benchstat ../private/base.txt ../private/new.txt ``` Results: ``` goos: darwin goarch: arm64 pkg: go.opentelemetry.io/otel/sdk/trace cpu: Apple M2 Max │ ../private/base.txt │ ../private/new.txt │ │ sec/op │ sec/op vs base │ Truncate/Unlimited-12 0.2086n ± 1% 0.2140n ± 3% +2.59% (p=0.017 n=10) Truncate/Zero-12 0.3048n ± 0% 0.3070n ± 1% +0.71% (p=0.014 n=10) Truncate/Short-12 0.2083n ± 2% 0.2097n ± 1% ~ (p=0.148 n=10) Truncate/ASCII-12 0.6870n ± 0% 0.6855n ± 0% ~ (p=0.493 n=10) Truncate/ValidUTF-8-12 1.298n ± 0% 1.302n ± 1% +0.31% (p=0.003 n=10) Truncate/InvalidUTF-8-12 9.457n ± 0% 9.420n ± 1% ~ (p=0.529 n=10) Truncate/MixedUTF-8-12 17.30n ± 1% 17.29n ± 0% ~ (p=0.359 n=10) RecordingSpanSetAttributes/WithLimit/false-12 2.055µ ± 1% 2.082µ ± 9% +1.29% (p=0.014 n=10) RecordingSpanSetAttributes/WithLimit/true-12 4.368µ ± 0% 4.364µ ± 0% -0.08% (p=0.049 n=10) SpanEnd-12 72.57n ± 17% 73.75n ± 16% ~ (p=0.853 n=10) TraceStart/with_a_simple_span-12 320.1n ± 10% 314.6n ± 10% ~ (p=0.165 n=10) TraceStart/with_several_links-12 432.7n ± 2% 429.4n ± 1% ~ (p=0.063 n=10) TraceStart/with_attributes-12 477.3n ± 1% 468.1n ± 6% -1.94% (p=0.005 n=10) SpanLimits/AttributeValueLengthLimit-12 4.401µ ± 1% 4.439µ ± 2% ~ (p=0.089 n=10) SpanLimits/AttributeCountLimit-12 4.125µ ± 1% 4.151µ ± 1% +0.62% (p=0.014 n=10) SpanLimits/EventCountLimit-12 3.900µ ± 2% 3.935µ ± 1% +0.88% (p=0.023 n=10) SpanLimits/LinkCountLimit-12 3.870µ ± 2% 3.901µ ± 1% ~ (p=0.148 n=10) SpanLimits/AttributePerEventCountLimit-12 4.212µ ± 1% 4.243µ ± 1% +0.75% (p=0.008 n=10) SpanLimits/AttributePerLinkCountLimit-12 4.200µ ± 1% 4.224µ ± 0% +0.57% (p=0.041 n=10) SpanSetAttributesOverCapacity-12 1.661µ ± 1% 1.653µ ± 0% -0.48% (p=0.049 n=10) StartEndSpan/AlwaysSample-12 317.9n ± 0% 316.5n ± 0% -0.44% (p=0.007 n=10) StartEndSpan/NeverSample-12 152.3n ± 0% 152.0n ± 0% -0.23% (p=0.005 n=10) SpanWithAttributes_4/AlwaysSample-12 527.2n ± 0% 532.4n ± 1% +1.00% (p=0.000 n=10) SpanWithAttributes_4/NeverSample-12 240.6n ± 0% 241.6n ± 0% +0.46% (p=0.000 n=10) SpanWithAttributes_8/AlwaysSample-12 704.5n ± 0% 718.3n ± 1% +1.97% (p=0.000 n=10) SpanWithAttributes_8/NeverSample-12 325.0n ± 0% 327.2n ± 1% +0.68% (p=0.000 n=10) SpanWithAttributes_all/AlwaysSample-12 576.8n ± 0% 584.7n ± 1% +1.37% (p=0.000 n=10) SpanWithAttributes_all/NeverSample-12 264.6n ± 1% 263.3n ± 0% -0.47% (p=0.045 n=10) SpanWithAttributes_all_2x/AlwaysSample-12 818.6n ± 1% 834.9n ± 0% +1.98% (p=0.000 n=10) SpanWithAttributes_all_2x/NeverSample-12 378.3n ± 0% 382.9n ± 1% +1.23% (p=0.000 n=10) SpanWithEvents_4/AlwaysSample-12 715.1n ± 1% 721.1n ± 0% +0.83% (p=0.003 n=10) SpanWithEvents_4/NeverSample-12 156.1n ± 1% 155.1n ± 1% -0.64% (p=0.002 n=10) SpanWithEvents_8/AlwaysSample-12 1.098µ ± 0% 1.104µ ± 0% +0.55% (p=0.000 n=10) SpanWithEvents_8/NeverSample-12 158.8n ± 0% 158.6n ± 1% ~ (p=0.288 n=10) SpanWithEvents_WithStackTrace/AlwaysSample-12 438.8n ± 0% 438.5n ± 0% ~ (p=0.868 n=10) SpanWithEvents_WithStackTrace/NeverSample-12 168.2n ± 1% 167.4n ± 1% -0.48% (p=0.014 n=10) SpanWithEvents_WithTimestamp/AlwaysSample-12 430.6n ± 0% 432.9n ± 0% +0.53% (p=0.001 n=10) SpanWithEvents_WithTimestamp/NeverSample-12 193.7n ± 0% 190.1n ± 1% -1.91% (p=0.000 n=10) TraceID_DotString-12 42.37n ± 0% 24.80n ± 0% -41.45% (p=0.000 n=10) SpanID_DotString-12 31.30n ± 0% 17.22n ± 0% -44.98% (p=0.000 n=10) SpanProcessorOnEnd/batch:_10,_spans:_10-12 163.3n ± 0% 163.4n ± 0% ~ (p=0.120 n=10) SpanProcessorOnEnd/batch:_10,_spans:_100-12 1.639µ ± 0% 1.635µ ± 0% -0.27% (p=0.000 n=10) SpanProcessorOnEnd/batch:_100,_spans:_10-12 163.3n ± 0% 163.2n ± 0% ~ (p=0.115 n=10) SpanProcessorOnEnd/batch:_100,_spans:_100-12 1.636µ ± 0% 1.635µ ± 1% ~ (p=0.509 n=10) SpanProcessorVerboseLogging-12 6.769µ ± 2% 6.600µ ± 2% -2.49% (p=0.030 n=10) geomean 221.4n 216.4n -2.29% │ ../private/base.txt │ ../private/new.txt │ │ B/op │ B/op vs base │ Truncate/Unlimited-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Zero-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Short-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ASCII-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ValidUTF-8-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/InvalidUTF-8-12 16.00 ± 0% 16.00 ± 0% ~ (p=1.000 n=10) ¹ Truncate/MixedUTF-8-12 32.00 ± 0% 32.00 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/false-12 6.891Ki ± 0% 6.891Ki ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/true-12 7.023Ki ± 0% 7.023Ki ± 0% ~ (p=1.000 n=10) ¹ SpanEnd-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_a_simple_span-12 528.0 ± 0% 528.0 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_several_links-12 704.0 ± 0% 704.0 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_attributes-12 784.0 ± 0% 784.0 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributeValueLengthLimit-12 10.56Ki ± 0% 10.56Ki ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributeCountLimit-12 9.844Ki ± 0% 9.844Ki ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/EventCountLimit-12 9.422Ki ± 0% 9.422Ki ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/LinkCountLimit-12 9.031Ki ± 0% 9.031Ki ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributePerEventCountLimit-12 10.47Ki ± 0% 10.47Ki ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributePerLinkCountLimit-12 10.47Ki ± 0% 10.47Ki ± 0% ~ (p=1.000 n=10) ¹ SpanSetAttributesOverCapacity-12 592.0 ± 0% 592.0 ± 0% ~ (p=1.000 n=10) ¹ StartEndSpan/AlwaysSample-12 528.0 ± 0% 528.0 ± 0% ~ (p=1.000 n=10) ¹ StartEndSpan/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/AlwaysSample-12 1.016Ki ± 0% 1.016Ki ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/NeverSample-12 400.0 ± 0% 400.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/AlwaysSample-12 1.516Ki ± 0% 1.516Ki ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/NeverSample-12 656.0 ± 0% 656.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/AlwaysSample-12 1.141Ki ± 0% 1.141Ki ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/NeverSample-12 464.0 ± 0% 464.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/AlwaysSample-12 1.891Ki ± 0% 1.891Ki ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/NeverSample-12 848.0 ± 0% 848.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/AlwaysSample-12 1.016Ki ± 0% 1.016Ki ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/AlwaysSample-12 1.641Ki ± 0% 1.641Ki ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/NeverSample-12 144.0 ± 0% 144.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/AlwaysSample-12 624.0 ± 0% 624.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/NeverSample-12 160.0 ± 0% 160.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/AlwaysSample-12 648.0 ± 0% 648.0 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/NeverSample-12 184.0 ± 0% 184.0 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorVerboseLogging-12 9.547Ki ± 0% 9.547Ki ± 0% ~ (p=1.000 n=10) ¹ geomean ² +0.00% ² ¹ all samples are equal ² summaries must be >0 to compute geomean │ ../private/base.txt │ ../private/new.txt │ │ allocs/op │ allocs/op vs base │ Truncate/Unlimited-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Zero-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/Short-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ASCII-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/ValidUTF-8-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/InvalidUTF-8-12 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹ Truncate/MixedUTF-8-12 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/false-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ RecordingSpanSetAttributes/WithLimit/true-12 10.00 ± 0% 10.00 ± 0% ~ (p=1.000 n=10) ¹ SpanEnd-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_a_simple_span-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_several_links-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ TraceStart/with_attributes-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributeValueLengthLimit-12 41.00 ± 0% 41.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributeCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/EventCountLimit-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/LinkCountLimit-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributePerEventCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanLimits/AttributePerLinkCountLimit-12 38.00 ± 0% 38.00 ± 0% ~ (p=1.000 n=10) ¹ SpanSetAttributesOverCapacity-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ StartEndSpan/AlwaysSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ StartEndSpan/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_4/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_8/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithAttributes_all_2x/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/AlwaysSample-12 5.000 ± 0% 5.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_4/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/AlwaysSample-12 6.000 ± 0% 6.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_8/NeverSample-12 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/AlwaysSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithStackTrace/NeverSample-12 3.000 ± 0% 3.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/AlwaysSample-12 5.000 ± 0% 5.000 ± 0% ~ (p=1.000 n=10) ¹ SpanWithEvents_WithTimestamp/NeverSample-12 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_10,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_10-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorOnEnd/batch:_100,_spans:_100-12 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ SpanProcessorVerboseLogging-12 35.00 ± 0% 35.00 ± 0% ~ (p=1.000 n=10) ¹ geomean ² +0.00% ² ¹ all samples are equal ² summaries must be >0 to compute geomean ``` ### Benchstate for parsing ``` goos: darwin goarch: arm64 pkg: go.opentelemetry.io/otel/sdk/trace cpu: Apple M2 Max │ ../private/base_hex.txt │ ../private/new_hex.txt │ │ sec/op │ sec/op vs base │ TraceIDFromHex-12 56.47n ± 0% 15.96n ± 0% -71.74% (p=0.000 n=10) SpanIDFromHex-12 34.680n ± 0% 8.742n ± 1% -74.79% (p=0.000 n=10) geomean 44.26n 11.81n -73.31% │ ../private/base_hex.txt │ ../private/new_hex.txt │ │ B/op │ B/op vs base │ TraceIDFromHex-12 16.00 ± 0% 0.00 ± 0% -100.00% (p=0.000 n=10) SpanIDFromHex-12 8.000 ± 0% 0.000 ± 0% -100.00% (p=0.000 n=10) geomean 11.31 ? ¹ ² ¹ summaries must be >0 to compute geomean ² ratios must be >0 to compute geomean │ ../private/base_hex.txt │ ../private/new_hex.txt │ │ allocs/op │ allocs/op vs base │ TraceIDFromHex-12 1.000 ± 0% 0.000 ± 0% -100.00% (p=0.000 n=10) SpanIDFromHex-12 1.000 ± 0% 0.000 ± 0% -100.00% (p=0.000 n=10) geomean 1.000 ? ¹ ² ¹ summaries must be >0 to compute geomean ² ratios must be >0 to compute geomean ``` Issue: open-telemetry#6721
Added a benchmark for parsing the hex. It's about 4x faster and doesn't allocate.
|
Uh oh!
There was an error while loading. Please reload this page.
Problem Statement
I'm exploring ways to optimize the trace functionality and wanted to gauge the appetite for optimization.
I'm willing to send PRs.
Proposed Solution
There are a few areas I've exprimented with in https://github.com/jschaf/observe. Ranked roughly in terms of feasibility, impact, and long term maintenance costs.
Use atomics for Span.End instead of a mutex. Provides about a 1.5x speed up on the Span.End benchmark. As a side benefit, reduces the Span size by 16 bytes since time.Time takes 24 bytes.
Inline hex encoding and decoding for TraceID and SpanID. Provides about a 2x speedup for parsing (27 ns to 12 ns) and reduces allocations to 0.
Zero allocation state parsing. This is a fair bit more complex than the current parsing, but has about the same line count. Provides about a 1.8x speed up and reduces allocations to zero.
[Still baking] Get syscall.Gettimeofday directly instead of time.Now. Saves about 15 ns compare to 30 ns for time.Now. I suspect there's a bunch of unhandled complexity here. It'd be swell if there was an alternative time library that handled this.
Alternatives
Doing nothing is perfectly reasonable.
Prior Art
https://www.pingcap.com/blog/how-we-trace-a-kv-database-with-less-than-5-percent-performance-impact/: They squeeze out performance using time-stamp counters and thread local state, both of which would be difficult to emulate in Go.
The text was updated successfully, but these errors were encountered: