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:
parent
cf7c4e5328
commit
e554562513
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user