Skip to content

Commit

Permalink
log: Add benchmark tests (#4958)
Browse files Browse the repository at this point in the history
  • Loading branch information
MrAlias committed Feb 22, 2024
1 parent 7b3382e commit 6ea99af
Show file tree
Hide file tree
Showing 2 changed files with 375 additions and 0 deletions.
255 changes: 255 additions & 0 deletions log/keyvalue_bench_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package log_test

import (
"testing"

"go.opentelemetry.io/otel/log"
)

// Store results in a file scope var to ensure compiler does not optimize the
// test away.
var (
outV log.Value
outKV log.KeyValue

outAny any
outBool bool
outFloat64 float64
outInt64 int64
outMap []log.KeyValue
outSlice []log.Value
outStr string
)

func BenchmarkBool(b *testing.B) {
const k, v = "bool", true

b.Run("Value", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outV = log.BoolValue(v)
}
})
b.Run("KeyValue", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outKV = log.Bool(k, v)
}
})

kv := log.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("AsAny", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outAny = kv.Value.AsAny()
}
})
}

func BenchmarkFloat64(b *testing.B) {
const k, v = "float64", 3.0

b.Run("Value", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outV = log.Float64Value(v)
}
})
b.Run("KeyValue", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outKV = log.Float64(k, v)
}
})

kv := log.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("AsAny", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outAny = kv.Value.AsAny()
}
})
}

func BenchmarkInt(b *testing.B) {
const k, v = "int", 32

b.Run("Value", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outV = log.IntValue(v)
}
})
b.Run("KeyValue", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outKV = log.Int(k, v)
}
})

kv := log.Int(k, v)
b.Run("AsInt64", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outInt64 = kv.Value.AsInt64()
}
})
b.Run("AsAny", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outAny = kv.Value.AsAny()
}
})
}

func BenchmarkInt64(b *testing.B) {
const k, v = "int64", int64(32)

b.Run("Value", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outV = log.Int64Value(v)
}
})
b.Run("KeyValue", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outKV = log.Int64(k, v)
}
})

kv := log.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("AsAny", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outAny = kv.Value.AsAny()
}
})
}

func BenchmarkMap(b *testing.B) {
const k = "map"
v := []log.KeyValue{log.Bool("b", true), log.Int("i", 1)}

b.Run("Value", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outV = log.MapValue(v...)
}
})
b.Run("KeyValue", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outKV = log.Map(k, v...)
}
})

kv := log.Map(k, v...)
b.Run("AsMap", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outMap = kv.Value.AsMap()
}
})
b.Run("AsAny", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outAny = kv.Value.AsAny()
}
})
}

func BenchmarkSlice(b *testing.B) {
const k = "slice"
v := []log.Value{log.BoolValue(true), log.IntValue(1)}

b.Run("Value", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outV = log.SliceValue(v...)
}
})
b.Run("KeyValue", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outKV = log.Slice(k, v...)
}
})

kv := log.Slice(k, v...)
b.Run("AsSlice", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outSlice = kv.Value.AsSlice()
}
})
b.Run("AsAny", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outAny = kv.Value.AsAny()
}
})
}

func BenchmarkString(b *testing.B) {
const k, v = "str", "value"

b.Run("Value", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outV = log.StringValue(v)
}
})
b.Run("KeyValue", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outKV = log.String(k, v)
}
})

kv := log.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("AsAny", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
outAny = kv.Value.AsAny()
}
})
}
120 changes: 120 additions & 0 deletions log/record_bench_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package log_test

import (
"testing"
"time"

"go.opentelemetry.io/otel/log"
)

func BenchmarkRecord(b *testing.B) {
var (
tStamp time.Time
sev log.Severity
text string
body log.Value
attr log.KeyValue
n int
)

b.Run("Timestamp", func(b *testing.B) {
b.ReportAllocs()
for n := 0; n < b.N; n++ {
var r log.Record
r.SetTimestamp(y2k)
tStamp = r.Timestamp()
}
})

b.Run("ObservedTimestamp", func(b *testing.B) {
b.ReportAllocs()
for n := 0; n < b.N; n++ {
var r log.Record
r.SetObservedTimestamp(y2k)
tStamp = r.ObservedTimestamp()
}
})

b.Run("Severity", func(b *testing.B) {
b.ReportAllocs()
for n := 0; n < b.N; n++ {
var r log.Record
r.SetSeverity(log.SeverityDebug)
sev = r.Severity()
}
})

b.Run("SeverityText", func(b *testing.B) {
b.ReportAllocs()
for n := 0; n < b.N; n++ {
var r log.Record
r.SetSeverityText("text")
text = r.SeverityText()
}
})

bodyVal := log.BoolValue(true)
b.Run("Body", func(b *testing.B) {
b.ReportAllocs()
for n := 0; n < b.N; n++ {
var r log.Record
r.SetBody(bodyVal)
body = r.Body()
}
})

attrs10 := []log.KeyValue{
log.Bool("b1", true),
log.Int("i1", 324),
log.Float64("f1", -230.213),
log.String("s1", "value1"),
log.Map("m1", log.Slice("slice1", log.BoolValue(true))),
log.Bool("b2", false),
log.Int("i2", 39847),
log.Float64("f2", 0.382964329),
log.String("s2", "value2"),
log.Map("m2", log.Slice("slice2", log.BoolValue(false))),
}
attrs5 := attrs10[:5]
walk := func(kv log.KeyValue) bool {
attr = kv
return true
}
b.Run("Attributes", func(b *testing.B) {
b.Run("5", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
var r log.Record
r.AddAttributes(attrs5...)
n = r.AttributesLen()
r.WalkAttributes(walk)
}
})
b.Run("10", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
var r log.Record
r.AddAttributes(attrs10...)
n = r.AttributesLen()
r.WalkAttributes(walk)
}
})
})

// Convince the linter these values are used.
_, _, _, _, _, _ = tStamp, sev, text, body, attr, n
}

0 comments on commit 6ea99af

Please sign in to comment.