Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Return spec-compliant `TraceIdRatioBased` description. This is a breaking behavioral change, but it is necessary to
make the implementation [spec-compliant](https://opentelemetry.io/docs/specs/otel/trace/sdk/#traceidratiobased). (#8027)

### Changed
Comment thread
MrAlias marked this conversation as resolved.
Outdated

- Refactor slice handling in `go.opentelemetry.io/otel/attribute` to optimize short slice values with fixed-size fast paths. (#8039)

<!-- Released section -->
<!-- Don't change this section unless doing release -->

Expand Down
248 changes: 149 additions & 99 deletions attribute/benchmark_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,28 +60,38 @@ func BenchmarkBool(b *testing.B) {
}

func BenchmarkBoolSlice(b *testing.B) {
k, v := "bool slice", []bool{true, false, true}
kv := attribute.BoolSlice(k, v)
for _, bench := range []struct {
name string
v []bool
}{
{name: "Len2", v: []bool{true, false}},
{name: "Len8", v: []bool{true, false, true, false, true, false, true, false}},
} {
b.Run(bench.name, func(b *testing.B) {
k, v := "bool slice", bench.v
kv := attribute.BoolSlice(k, v)

b.Run("Value", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outV = attribute.BoolSliceValue(v)
}
})
b.Run("KeyValue", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outKV = attribute.BoolSlice(k, v)
}
})
b.Run("AsBoolSlice", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outBoolSlice = kv.Value.AsBoolSlice()
}
})
b.Run("Emit", benchmarkEmit(kv))
b.Run("Value", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outV = attribute.BoolSliceValue(v)
}
})
b.Run("KeyValue", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outKV = attribute.BoolSlice(k, v)
}
})
b.Run("AsBoolSlice", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outBoolSlice = kv.Value.AsBoolSlice()
}
})
b.Run("Emit", benchmarkEmit(kv))
})
}
}

func BenchmarkInt(b *testing.B) {
Expand All @@ -104,22 +114,32 @@ func BenchmarkInt(b *testing.B) {
}

func BenchmarkIntSlice(b *testing.B) {
k, v := "int slice", []int{42, -3, 12}
kv := attribute.IntSlice(k, v)
for _, bench := range []struct {
name string
v []int
}{
{name: "Len2", v: []int{42, -3}},
{name: "Len8", v: []int{42, -3, 12, 7, 9, 11, -5, 0}},
} {
b.Run(bench.name, func(b *testing.B) {
k, v := "int slice", bench.v
kv := attribute.IntSlice(k, v)

b.Run("Value", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outV = attribute.IntSliceValue(v)
}
})
b.Run("KeyValue", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outKV = attribute.IntSlice(k, v)
}
})
b.Run("Emit", benchmarkEmit(kv))
b.Run("Value", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outV = attribute.IntSliceValue(v)
}
})
b.Run("KeyValue", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outKV = attribute.IntSlice(k, v)
}
})
b.Run("Emit", benchmarkEmit(kv))
})
}
}

func BenchmarkInt64(b *testing.B) {
Expand Down Expand Up @@ -148,28 +168,38 @@ func BenchmarkInt64(b *testing.B) {
}

func BenchmarkInt64Slice(b *testing.B) {
k, v := "int64 slice", []int64{42, -3, 12}
kv := attribute.Int64Slice(k, v)
for _, bench := range []struct {
name string
v []int64
}{
{name: "Len2", v: []int64{42, -3}},
{name: "Len8", v: []int64{42, -3, 12, 7, 9, 11, -5, 0}},
} {
b.Run(bench.name, func(b *testing.B) {
k, v := "int64 slice", bench.v
kv := attribute.Int64Slice(k, v)

b.Run("Value", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outV = attribute.Int64SliceValue(v)
}
})
b.Run("KeyValue", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outKV = attribute.Int64Slice(k, v)
}
})
b.Run("AsInt64Slice", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outInt64Slice = kv.Value.AsInt64Slice()
}
})
b.Run("Emit", benchmarkEmit(kv))
b.Run("Value", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outV = attribute.Int64SliceValue(v)
}
})
b.Run("KeyValue", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outKV = attribute.Int64Slice(k, v)
}
})
b.Run("AsInt64Slice", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outInt64Slice = kv.Value.AsInt64Slice()
}
})
b.Run("Emit", benchmarkEmit(kv))
})
}
}

func BenchmarkFloat64(b *testing.B) {
Expand Down Expand Up @@ -198,28 +228,38 @@ func BenchmarkFloat64(b *testing.B) {
}

func BenchmarkFloat64Slice(b *testing.B) {
k, v := "float64 slice", []float64{42, -3, 12}
kv := attribute.Float64Slice(k, v)
for _, bench := range []struct {
name string
v []float64
}{
{name: "Len2", v: []float64{42, -3}},
{name: "Len8", v: []float64{42, -3, 12, 7, 9, 11, -5, 0}},
} {
b.Run(bench.name, func(b *testing.B) {
k, v := "float64 slice", bench.v
kv := attribute.Float64Slice(k, v)

b.Run("Value", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outV = attribute.Float64SliceValue(v)
}
})
b.Run("KeyValue", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outKV = attribute.Float64Slice(k, v)
}
})
b.Run("AsFloat64Slice", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outFloat64Slice = kv.Value.AsFloat64Slice()
}
})
b.Run("Emit", benchmarkEmit(kv))
b.Run("Value", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outV = attribute.Float64SliceValue(v)
}
})
b.Run("KeyValue", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outKV = attribute.Float64Slice(k, v)
}
})
b.Run("AsFloat64Slice", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outFloat64Slice = kv.Value.AsFloat64Slice()
}
})
b.Run("Emit", benchmarkEmit(kv))
})
}
}

func BenchmarkString(b *testing.B) {
Expand Down Expand Up @@ -248,28 +288,38 @@ func BenchmarkString(b *testing.B) {
}

func BenchmarkStringSlice(b *testing.B) {
k, v := "float64 slice", []string{"forty-two", "negative three", "twelve"}
kv := attribute.StringSlice(k, v)
for _, bench := range []struct {
name string
v []string
}{
{name: "Len2", v: []string{"forty-two", "negative three"}},
{name: "Len8", v: []string{"forty-two", "negative three", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen"}},
} {
b.Run(bench.name, func(b *testing.B) {
k, v := "string slice", bench.v
kv := attribute.StringSlice(k, v)

b.Run("Value", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outV = attribute.StringSliceValue(v)
}
})
b.Run("KeyValue", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outKV = attribute.StringSlice(k, v)
}
})
b.Run("AsStringSlice", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outStrSlice = kv.Value.AsStringSlice()
}
})
b.Run("Emit", benchmarkEmit(kv))
b.Run("Value", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outV = attribute.StringSliceValue(v)
}
})
b.Run("KeyValue", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outKV = attribute.StringSlice(k, v)
}
})
b.Run("AsStringSlice", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outStrSlice = kv.Value.AsStringSlice()
}
})
b.Run("Emit", benchmarkEmit(kv))
})
}
}

func BenchmarkSetEquals(b *testing.B) {
Expand Down
Loading
Loading