From 08687b2d91b32bb72f0fd98ea7e558e6cac8875b Mon Sep 17 00:00:00 2001 From: Tyler Yahn Date: Fri, 6 Aug 2021 10:30:53 -0700 Subject: [PATCH] Refactor attributes benchmark tests 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 | 380 ++++++++++++++++++------------------ 1 file changed, 190 insertions(+), 190 deletions(-) diff --git a/attribute/benchmark_test.go b/attribute/benchmark_test.go index 1448d5d833f..4a037d283f7 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) - - boolVal = true - boolKeyVal = attribute.Bool("bool", boolVal) - - intVal = int(1) - intKeyVal = attribute.Int("int", intVal) - - int8Val = int8(1) - int8KeyVal = attribute.Int("int8", int(int8Val)) + outV attribute.Value + outKV attribute.KeyValue - 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 BenchmarkArrayKeyAny(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = attribute.Any("array", arrayVal) - } -} - -func BenchmarkBoolKey(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = attribute.Bool("bool", boolVal) - } +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 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 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 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 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 BenchmarkInt8(b *testing.B) { + b.Run("Any", benchmarkAny("int8", int8(42))) +} + +func BenchmarkInt16(b *testing.B) { + b.Run("Any", benchmarkAny("int16", int16(42))) +} + +func BenchmarkInt32(b *testing.B) { + b.Run("Any", benchmarkAny("int32", int32(42))) +} + +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 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 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 BenchmarkBytes(b *testing.B) { + b.Run("Any", benchmarkAny("bytes", []byte("bytes"))) } -func BenchmarkBoolKeyAny(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = attribute.Any("bool", boolVal) - } -} - -func BenchmarkIntKey(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = attribute.Int("int", intVal) - } -} - -func BenchmarkIntKeyAny(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = attribute.Any("int", intVal) - } -} - -func BenchmarkInt8KeyAny(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = attribute.Any("int8", int8Val) - } -} - -func BenchmarkInt16KeyAny(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = attribute.Any("int16", int16Val) - } -} - -func BenchmarkInt64Key(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = attribute.Int64("int64", int64Val) - } -} - -func BenchmarkInt64KeyAny(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = attribute.Any("int64", int64Val) - } -} - -func BenchmarkFloat64Key(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = attribute.Float64("float64", float64Val) - } -} - -func BenchmarkFloat64KeyAny(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = attribute.Any("float64", float64Val) - } -} - -func BenchmarkStringKey(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = attribute.String("string", stringVal) - } -} - -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() - } -} +type test struct{} -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{})) }