1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2025-09-16 09:26:25 +02:00

Add a key benchmark, use reflection in key.Infer() (#679)

* Add a key benchmark, optimize SDK SetAttribute

* Use reflect in key.Infer

* Move to separate benchmark file; remove pointer test; remove dead comment

* Run go mod tidy

* Add license header

* Use the reflect scalar accessors

Co-authored-by: Liz Fong-Jones <lizf@honeycomb.io>
This commit is contained in:
Joshua MacDonald
2020-04-30 13:06:00 -07:00
committed by GitHub
parent a053038e52
commit 4c9a29d2d7
3 changed files with 111 additions and 25 deletions

75
api/key/benchmark_test.go Normal file
View File

@@ -0,0 +1,75 @@
// 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 key_test
import (
"context"
"testing"
"go.opentelemetry.io/otel/api/global"
"go.opentelemetry.io/otel/api/key"
"go.opentelemetry.io/otel/api/trace"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
)
// Note: The tests below load a real SDK to ensure the compiler isn't optimizing
// the test based on global analysis limited to the NoopSpan implementation.
func getSpan() trace.Span {
_, sp := global.Tracer("Test").Start(context.Background(), "Span")
tr, _ := sdktrace.NewProvider()
global.SetTraceProvider(tr)
return sp
}
func BenchmarkKeyInfer(b *testing.B) {
for i := 0; i < b.N; i++ {
key.Infer("Attr", int(256))
}
}
func BenchmarkMultiNoKeyInference(b *testing.B) {
sp := getSpan()
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
sp.SetAttributes(key.Int("Attr", 1))
}
}
func BenchmarkMultiWithKeyInference(b *testing.B) {
sp := getSpan()
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
sp.SetAttributes(key.Infer("Attr", 1))
}
}
func BenchmarkSingleWithKeyInferenceValue(b *testing.B) {
sp := getSpan()
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
sp.SetAttribute("Attr", 1)
}
b.StopTimer()
}

View File

@@ -16,6 +16,7 @@ package key
import (
"fmt"
"reflect"
"go.opentelemetry.io/otel/api/core"
)
@@ -96,30 +97,37 @@ func Uint(k string, v uint) core.KeyValue {
// Infer creates a new key-value pair instance with a passed name and
// automatic type inference. This is slower, and not type-safe.
func Infer(k string, value interface{}) core.KeyValue {
switch v := value.(type) {
case bool:
return Bool(k, v)
case int:
return Int(k, v)
case uint:
return Uint(k, v)
case int32:
return Int32(k, v)
case int64:
return Int64(k, v)
case uint32:
return Uint32(k, v)
case uint64:
return Uint64(k, v)
case float32:
return Float32(k, v)
case float64:
return Float64(k, v)
case string:
return String(k, v)
case fmt.Stringer:
return Stringer(k, v)
default:
return String(k, fmt.Sprint(v))
if value == nil {
return String(k, "<nil>")
}
if stringer, ok := value.(fmt.Stringer); ok {
return String(k, stringer.String())
}
rv := reflect.ValueOf(value)
switch rv.Kind() {
case reflect.Bool:
return Bool(k, rv.Bool())
case reflect.Int, reflect.Int8, reflect.Int16:
return Int(k, int(rv.Int()))
case reflect.Int32:
return Int32(k, int32(rv.Int()))
case reflect.Int64:
return Int64(k, int64(rv.Int()))
case reflect.Uint, reflect.Uint8, reflect.Uint16:
return Uint(k, uint(rv.Uint()))
case reflect.Uint32:
return Uint32(k, uint32(rv.Uint()))
case reflect.Uint64, reflect.Uintptr:
return Uint64(k, rv.Uint())
case reflect.Float32:
return Float32(k, float32(rv.Float()))
case reflect.Float64:
return Float64(k, rv.Float())
case reflect.String:
return String(k, rv.Interface().(string))
}
return String(k, fmt.Sprint(rv.Interface()))
}

View File

@@ -1,8 +1,10 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/DataDog/sketches-go v0.0.0-20190923095040-43f19ad77ff7 h1:qELHH0AWCvf98Yf+CNIJx9vOZOfHFDDzgDRYsnNk/vs=
github.com/DataDog/sketches-go v0.0.0-20190923095040-43f19ad77ff7/go.mod h1:Q5DbzQ+3AkgGwymQO7aZFNP7ns2lZKGtvRBzRXfdi60=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/benbjohnson/clock v1.0.0 h1:78Jk/r6m4wCi6sndMpty7A//t4dw/RW5fV4ZgDVfX1w=
github.com/benbjohnson/clock v1.0.0/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
@@ -27,6 +29,7 @@ github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8l
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=