From 2b0e139e1028a79bc58e077544127ce9b9ba5b28 Mon Sep 17 00:00:00 2001 From: Tyler Yahn Date: Wed, 11 Aug 2021 08:49:10 -0700 Subject: [PATCH] Refactor attributes benchmark tests (#2167) Group benchmarks by type for easier understanding and filtering. Save output of function calls in benchmarks to file level vars to ensure the compiler does not optimize away the test. Unify testing functionality for common benchmark tasks. --- attribute/benchmark_test.go | 330 ++++++++++++++++++------------------ 1 file changed, 165 insertions(+), 165 deletions(-) diff --git a/attribute/benchmark_test.go b/attribute/benchmark_test.go index 1448d5d83..4a037d283 100644 --- a/attribute/benchmark_test.go +++ b/attribute/benchmark_test.go @@ -20,201 +20,201 @@ import ( "go.opentelemetry.io/otel/attribute" ) -type test struct{} - +// Store results in a file scope var to ensure compiler does not optimize the +// test away. var ( - arrayVal = []string{"one", "two"} - arrayKeyVal = attribute.Array("array", arrayVal) + outV attribute.Value + outKV attribute.KeyValue - boolVal = true - boolKeyVal = attribute.Bool("bool", boolVal) - - intVal = int(1) - intKeyVal = attribute.Int("int", intVal) - - int8Val = int8(1) - int8KeyVal = attribute.Int("int8", int(int8Val)) - - int16Val = int16(1) - int16KeyVal = attribute.Int("int16", int(int16Val)) - - int64Val = int64(1) - int64KeyVal = attribute.Int64("int64", int64Val) - - float64Val = float64(1.0) - float64KeyVal = attribute.Float64("float64", float64Val) - - stringVal = "string" - stringKeyVal = attribute.String("string", stringVal) - - bytesVal = []byte("bytes") - structVal = test{} + outBool bool + outInt64 int64 + outFloat64 float64 + outStr string ) -func BenchmarkArrayKey(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = attribute.Array("array", arrayVal) +func benchmarkAny(k string, v interface{}) func(*testing.B) { + return func(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + outKV = attribute.Any(k, v) + } } } -func BenchmarkArrayKeyAny(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = attribute.Any("array", arrayVal) +func benchmarkEmit(kv attribute.KeyValue) func(*testing.B) { + return func(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + outStr = kv.Value.Emit() + } } } -func BenchmarkBoolKey(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = attribute.Bool("bool", boolVal) +func benchmarkArray(k string, v interface{}) func(*testing.B) { + a := attribute.Array(k, v) + return func(b *testing.B) { + b.Run("KeyValue", func(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + outKV = attribute.Array(k, v) + } + }) + b.Run("Emit", benchmarkEmit(a)) } } -func BenchmarkBoolKeyAny(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = attribute.Any("bool", boolVal) - } +func BenchmarkBool(b *testing.B) { + k, v := "bool", true + kv := attribute.Bool(k, v) + array := []bool{true, false, true} + + b.Run("Value", func(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + outV = attribute.BoolValue(v) + } + }) + b.Run("KeyValue", func(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + outKV = attribute.Bool(k, v) + } + }) + b.Run("AsBool", func(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + outBool = kv.Value.AsBool() + } + }) + b.Run("Any", benchmarkAny(k, v)) + b.Run("Emit", benchmarkEmit(kv)) + b.Run("Array", benchmarkArray(k, array)) } -func BenchmarkIntKey(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = attribute.Int("int", intVal) - } +func BenchmarkInt(b *testing.B) { + k, v := "int", int(42) + kv := attribute.Int(k, v) + array := []int{42, -3, 12} + + b.Run("Value", func(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + outV = attribute.IntValue(v) + } + }) + b.Run("KeyValue", func(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + outKV = attribute.Int(k, v) + } + }) + b.Run("Any", benchmarkAny(k, v)) + b.Run("Emit", benchmarkEmit(kv)) + b.Run("Array", benchmarkArray(k, array)) } -func BenchmarkIntKeyAny(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = attribute.Any("int", intVal) - } +func BenchmarkInt8(b *testing.B) { + b.Run("Any", benchmarkAny("int8", int8(42))) } -func BenchmarkInt8KeyAny(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = attribute.Any("int8", int8Val) - } +func BenchmarkInt16(b *testing.B) { + b.Run("Any", benchmarkAny("int16", int16(42))) } -func BenchmarkInt16KeyAny(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = attribute.Any("int16", int16Val) - } +func BenchmarkInt32(b *testing.B) { + b.Run("Any", benchmarkAny("int32", int32(42))) } -func BenchmarkInt64Key(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = attribute.Int64("int64", int64Val) - } +func BenchmarkInt64(b *testing.B) { + k, v := "int64", int64(42) + kv := attribute.Int64(k, v) + array := []int64{42, -3, 12} + + b.Run("Value", func(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + outV = attribute.Int64Value(v) + } + }) + b.Run("KeyValue", func(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + outKV = attribute.Int64(k, v) + } + }) + b.Run("AsInt64", func(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + outInt64 = kv.Value.AsInt64() + } + }) + b.Run("Any", benchmarkAny(k, v)) + b.Run("Emit", benchmarkEmit(kv)) + b.Run("Array", benchmarkArray(k, array)) } -func BenchmarkInt64KeyAny(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = attribute.Any("int64", int64Val) - } +func BenchmarkFloat64(b *testing.B) { + k, v := "float64", float64(42) + kv := attribute.Float64(k, v) + array := []float64{42, -3, 12} + + b.Run("Value", func(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + outV = attribute.Float64Value(v) + } + }) + b.Run("KeyValue", func(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + outKV = attribute.Float64(k, v) + } + }) + b.Run("AsFloat64", func(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + outFloat64 = kv.Value.AsFloat64() + } + }) + b.Run("Any", benchmarkAny(k, v)) + b.Run("Emit", benchmarkEmit(kv)) + b.Run("Array", benchmarkArray(k, array)) } -func BenchmarkFloat64Key(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = attribute.Float64("float64", float64Val) - } +func BenchmarkString(b *testing.B) { + k, v := "string", "42" + kv := attribute.String(k, v) + array := []string{"forty-two", "negative three", "twelve"} + + b.Run("Value", func(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + outV = attribute.StringValue(v) + } + }) + b.Run("KeyValue", func(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + outKV = attribute.String(k, v) + } + }) + b.Run("AsString", func(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + outStr = kv.Value.AsString() + } + }) + b.Run("Any", benchmarkAny(k, v)) + b.Run("Emit", benchmarkEmit(kv)) + b.Run("Array", benchmarkArray(k, array)) } -func BenchmarkFloat64KeyAny(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = attribute.Any("float64", float64Val) - } +func BenchmarkBytes(b *testing.B) { + b.Run("Any", benchmarkAny("bytes", []byte("bytes"))) } -func BenchmarkStringKey(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = attribute.String("string", stringVal) - } -} +type test struct{} -func BenchmarkStringKeyAny(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = attribute.Any("string", stringVal) - } -} - -func BenchmarkBytesKeyAny(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = attribute.Any("bytes", bytesVal) - } -} - -func BenchmarkStructKeyAny(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = attribute.Any("struct", structVal) - } -} - -func BenchmarkEmitArray(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = arrayKeyVal.Value.Emit() - } -} - -func BenchmarkEmitBool(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = boolKeyVal.Value.Emit() - } -} - -func BenchmarkEmitInt(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = intKeyVal.Value.Emit() - } -} - -func BenchmarkEmitInt8(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = int8KeyVal.Value.Emit() - } -} - -func BenchmarkEmitInt16(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = int16KeyVal.Value.Emit() - } -} - -func BenchmarkEmitInt64(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = int64KeyVal.Value.Emit() - } -} - -func BenchmarkEmitFloat64(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = float64KeyVal.Value.Emit() - } -} - -func BenchmarkEmitString(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = stringKeyVal.Value.Emit() - } +func BenchmarkStruct(b *testing.B) { + b.Run("Any", benchmarkAny("struct", test{})) }