1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2024-12-04 09:43:23 +02:00

Do not cache reflect.ValueOf() in metrics Labels (#649)

* Benchmark label iterator

* Remove cachedValue, a minor optimization
This commit is contained in:
Joshua MacDonald 2020-04-20 20:29:46 -07:00 committed by GitHub
parent cf7c4e5328
commit e554562513
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 9 deletions

View File

@ -554,3 +554,38 @@ func BenchmarkBatchRecord_8Labels_4Instruments(b *testing.B) {
func BenchmarkBatchRecord_8Labels_8Instruments(b *testing.B) {
benchmarkBatchRecord8Labels(b, 8)
}
// LabelIterator
func BenchmarkLabelIterator(b *testing.B) {
const labelCount = 1024
ctx := context.Background()
fix := newFixture(b)
var rec export.Record
fix.pcb = func(_ context.Context, processRec export.Record) error {
rec = processRec
return nil
}
keyValues := makeLabels(labelCount)
counter := fix.meter.NewInt64Counter("test.counter")
counter.Add(ctx, 1, keyValues...)
fix.sdk.Collect(ctx)
b.ResetTimer()
labels := rec.Labels()
iter := labels.Iter()
var val core.KeyValue
for i := 0; i < b.N; i++ {
if !iter.Next() {
iter = labels.Iter()
iter.Next()
}
val = iter.Label()
}
if false {
fmt.Println(val)
}
}

View File

@ -92,10 +92,6 @@ type (
// the labels, copied into an array of the correct
// size for use as a map key.
ordered orderedLabels
// cachedValue contains a `reflect.Value` of the `ordered`
// member
cachedValue reflect.Value
}
// mapkey uniquely describes a metric instrument in terms of
@ -174,8 +170,7 @@ var (
kvType = reflect.TypeOf(core.KeyValue{})
emptyLabels = labels{
ordered: [0]core.KeyValue{},
cachedValue: reflect.ValueOf([0]core.KeyValue{}),
ordered: [0]core.KeyValue{},
}
)
@ -393,13 +388,15 @@ func (m *SDK) makeLabels(kvs []core.KeyValue, sortSlice *sortedLabels) labels {
// NumLabels is a part of an implementation of the export.LabelStorage
// interface.
func (ls *labels) NumLabels() int {
return ls.cachedValue.Len()
return reflect.ValueOf(ls.ordered).Len()
}
// GetLabel is a part of an implementation of the export.LabelStorage
// interface.
func (ls *labels) GetLabel(idx int) core.KeyValue {
return ls.cachedValue.Index(idx).Interface().(core.KeyValue)
// Note: The Go compiler successfully avoids an allocation for
// the interface{} conversion here:
return reflect.ValueOf(ls.ordered).Index(idx).Interface().(core.KeyValue)
}
// Iter is a part of an implementation of the export.Labels interface.
@ -459,7 +456,6 @@ func computeOrderedLabels(kvs []core.KeyValue) labels {
if ls.ordered == nil {
ls.ordered = computeOrderedReflect(kvs)
}
ls.cachedValue = reflect.ValueOf(ls.ordered)
return ls
}