From ae6d29f4b144abc6634c307038d42beb4b5fa260 Mon Sep 17 00:00:00 2001 From: Damien Mathieu <42@dmathieu.com> Date: Tue, 16 Jul 2024 09:22:04 +0200 Subject: [PATCH] Refactor Batch Processor benchmark to really test OnEnd (#5600) This benchmark was not only testing the batch processor, since it was starting a span, and ending it. So the entire process of recording span was being accounted. This changes the benchmark to only account for the batch processor being tested, not the entire stack. Before: ``` pkg: go.opentelemetry.io/otel/sdk/trace BenchmarkSpanProcessor-10 137320 8696 ns/op 11184 B/op 155 allocs/op BenchmarkSpanProcessorVerboseLogging-10 135483 8881 ns/op 11184 B/op 155 allocs/op PASS ok go.opentelemetry.io/otel/sdk/trace 3.984s ``` After: ``` pkg: go.opentelemetry.io/otel/sdk/trace BenchmarkSpanProcessorOnEnd/batch:_10,_spans:_10-10 6055572 173.2 ns/op 0 B/op 0 allocs/op BenchmarkSpanProcessorOnEnd/batch:_10,_spans:_100-10 684236 1733 ns/op 0 B/op 0 allocs/op BenchmarkSpanProcessorOnEnd/batch:_100,_spans:_10-10 6930391 173.8 ns/op 0 B/op 0 allocs/op BenchmarkSpanProcessorOnEnd/batch:_100,_spans:_100-10 677128 1731 ns/op 0 B/op 0 allocs/op BenchmarkSpanProcessorVerboseLogging-10 128823 9318 ns/op 11184 B/op 155 allocs/op PASS ok go.opentelemetry.io/otel/sdk/trace 6.763s ``` I haven't touched the verbose logging benchmark, as I suppose a benchmark with verbose logging could actually benefit from the entire stack. I also feel one benchmark testing the entire stack up to there could be nice. --- sdk/trace/batch_span_processor_test.go | 43 ++++++++++++++++---------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/sdk/trace/batch_span_processor_test.go b/sdk/trace/batch_span_processor_test.go index d0720ff5de9..51fdd6b65db 100644 --- a/sdk/trace/batch_span_processor_test.go +++ b/sdk/trace/batch_span_processor_test.go @@ -627,23 +627,32 @@ func TestBatchSpanProcessorConcurrentSafe(t *testing.T) { wg.Wait() } -func BenchmarkSpanProcessor(b *testing.B) { - tp := sdktrace.NewTracerProvider( - sdktrace.WithBatcher( - tracetest.NewNoopExporter(), - sdktrace.WithMaxExportBatchSize(10), - )) - tracer := tp.Tracer("bench") - ctx := context.Background() - - b.ResetTimer() - b.ReportAllocs() - - for i := 0; i < b.N; i++ { - for j := 0; j < 10; j++ { - _, span := tracer.Start(ctx, "bench") - span.End() - } +func BenchmarkSpanProcessorOnEnd(b *testing.B) { + for _, bb := range []struct { + batchSize int + spansCount int + }{ + {batchSize: 10, spansCount: 10}, + {batchSize: 10, spansCount: 100}, + {batchSize: 100, spansCount: 10}, + {batchSize: 100, spansCount: 100}, + } { + b.Run(fmt.Sprintf("batch: %d, spans: %d", bb.batchSize, bb.spansCount), func(b *testing.B) { + bsp := sdktrace.NewBatchSpanProcessor( + tracetest.NewNoopExporter(), + sdktrace.WithMaxExportBatchSize(bb.batchSize), + ) + snap := tracetest.SpanStub{}.Snapshot() + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + // Ensure the export happens for every run + for j := 0; j < bb.spansCount; j++ { + bsp.OnEnd(snap) + } + } + }) } }