diff --git a/attribute/benchmark_test.go b/attribute/benchmark_test.go index d81bbe829..1822123e8 100644 --- a/attribute/benchmark_test.go +++ b/attribute/benchmark_test.go @@ -271,3 +271,59 @@ func BenchmarkStringSlice(b *testing.B) { }) b.Run("Emit", benchmarkEmit(kv)) } + +// BenchmarkEquivalentMapAccess measures how expensive it is to use +// Equivalent() as a map key. This is on the hot path for making synchronous +// measurements on the metrics API/SDK. It will likely be on the hot path for +// the trace and logs API/SDK in the future. +func BenchmarkEquivalentMapAccess(b *testing.B) { + b.Run("Empty", func(b *testing.B) { + benchmarkEquivalentMapAccess(b, attribute.EmptySet()) + }) + b.Run("1 string attribute", func(b *testing.B) { + set := attribute.NewSet(attribute.String("string", "42")) + benchmarkEquivalentMapAccess(b, &set) + }) + b.Run("10 string attributes", func(b *testing.B) { + set := attribute.NewSet( + attribute.String("a", "42"), + attribute.String("b", "42"), + attribute.String("c", "42"), + attribute.String("d", "42"), + attribute.String("e", "42"), + attribute.String("f", "42"), + attribute.String("g", "42"), + attribute.String("h", "42"), + attribute.String("i", "42"), + attribute.String("j", "42"), + ) + benchmarkEquivalentMapAccess(b, &set) + }) + b.Run("1 int attribute", func(b *testing.B) { + set := attribute.NewSet(attribute.Int("string", 42)) + benchmarkEquivalentMapAccess(b, &set) + }) + b.Run("10 int attributes", func(b *testing.B) { + set := attribute.NewSet( + attribute.Int("a", 42), + attribute.Int("b", 42), + attribute.Int("c", 42), + attribute.Int("d", 42), + attribute.Int("e", 42), + attribute.Int("f", 42), + attribute.Int("g", 42), + attribute.Int("h", 42), + attribute.Int("i", 42), + attribute.Int("j", 42), + ) + benchmarkEquivalentMapAccess(b, &set) + }) +} + +func benchmarkEquivalentMapAccess(b *testing.B, set *attribute.Set) { + values := map[attribute.Distinct]int{} + b.ResetTimer() + for range b.N { + values[set.Equivalent()]++ + } +}