From 4987a1dd4b94781c1bce7c50dd4cf5b539469d37 Mon Sep 17 00:00:00 2001 From: Damien Mathieu Date: Fri, 28 Jun 2024 11:51:09 +0200 Subject: [PATCH] Split the span start/end benchmarks and test start with links and attributes (#5554) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I was looking at the trace benchmarks, and noticed this one, which says it tests "span start", but ending the span is included within the data. So this change removes ending the span from the computation, and adds a new benchmark which only computes span end. benchstat for span start: ``` pkg: go.opentelemetry.io/otel/sdk/trace │ bench-main │ bench-branch │ │ sec/op │ sec/op vs base │ TraceStart-10 725.6n ± 3% 667.2n ± 2% -8.04% (p=0.000 n=10) │ bench-main │ bench-branch │ │ B/op │ B/op vs base │ TraceStart-10 704.0 ± 0% 704.0 ± 0% ~ (p=1.000 n=10) ¹ ¹ all samples are equal │ bench-main │ bench-branch │ │ allocs/op │ allocs/op vs base │ TraceStart-10 14.00 ± 0% 14.00 ± 0% ~ (p=1.000 n=10) ¹ ¹ all samples are equal ``` Benchmark for span end: ``` BenchmarkSpanEnd-10 16486819 147.7 ns/op 0 B/op 0 allocs/op ``` --- sdk/trace/span_test.go | 18 ++++++++++++++++ sdk/trace/trace_test.go | 47 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/sdk/trace/span_test.go b/sdk/trace/span_test.go index 4556da8e91a..38bf2b2e8a9 100644 --- a/sdk/trace/span_test.go +++ b/sdk/trace/span_test.go @@ -13,6 +13,7 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/trace" ) func TestSetStatus(t *testing.T) { @@ -277,3 +278,20 @@ func BenchmarkRecordingSpanSetAttributes(b *testing.B) { }) } } + +func BenchmarkSpanEnd(b *testing.B) { + tracer := NewTracerProvider().Tracer("") + ctx := trace.ContextWithSpanContext(context.Background(), trace.SpanContext{}) + + spans := make([]trace.Span, b.N) + for i := 0; i < b.N; i++ { + _, span := tracer.Start(ctx, "") + spans[i] = span + } + + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + spans[i].End() + } +} diff --git a/sdk/trace/trace_test.go b/sdk/trace/trace_test.go index 09dcb5eb3bf..87247d1f167 100644 --- a/sdk/trace/trace_test.go +++ b/sdk/trace/trace_test.go @@ -2112,11 +2112,48 @@ func BenchmarkTraceStart(b *testing.B) { tracer := NewTracerProvider().Tracer("") ctx := trace.ContextWithSpanContext(context.Background(), trace.SpanContext{}) - b.ReportAllocs() - b.ResetTimer() + l1 := trace.Link{SpanContext: trace.SpanContext{}, Attributes: []attribute.KeyValue{}} + l2 := trace.Link{SpanContext: trace.SpanContext{}, Attributes: []attribute.KeyValue{}} - for i := 0; i < b.N; i++ { - _, span := tracer.Start(ctx, "") - span.End() + links := []trace.Link{l1, l2} + + for _, tt := range []struct { + name string + options []trace.SpanStartOption + }{ + { + name: "with a simple span", + }, + { + name: "with several links", + options: []trace.SpanStartOption{ + trace.WithLinks(links...), + }, + }, + { + name: "with attributes", + options: []trace.SpanStartOption{ + trace.WithAttributes( + attribute.String("key1", "value1"), + attribute.String("key2", "value2"), + ), + }, + }, + } { + b.Run(tt.name, func(b *testing.B) { + spans := make([]trace.Span, b.N) + b.ReportAllocs() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + _, span := tracer.Start(ctx, "", tt.options...) + spans[i] = span + } + + b.StopTimer() + for i := 0; i < b.N; i++ { + spans[i].End() + } + }) } }