benchmark: measure label resolution in MetricVec
Signed-off-by: Stephen J Day <stephen.day@docker.com>
This commit is contained in:
parent
25db044749
commit
c4004ef5f6
|
@ -96,10 +96,7 @@ func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec {
|
|||
opts.ConstLabels,
|
||||
)
|
||||
return &CounterVec{
|
||||
MetricVec: MetricVec{
|
||||
children: map[uint64]Metric{},
|
||||
desc: desc,
|
||||
newMetric: func(lvs ...string) Metric {
|
||||
MetricVec: newMetricVec(desc, func(lvs ...string) Metric {
|
||||
result := &counter{value: value{
|
||||
desc: desc,
|
||||
valType: CounterValue,
|
||||
|
@ -107,8 +104,7 @@ func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec {
|
|||
}}
|
||||
result.init(result) // Init self-collection.
|
||||
return result
|
||||
},
|
||||
},
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -72,13 +72,9 @@ func NewGaugeVec(opts GaugeOpts, labelNames []string) *GaugeVec {
|
|||
opts.ConstLabels,
|
||||
)
|
||||
return &GaugeVec{
|
||||
MetricVec: MetricVec{
|
||||
children: map[uint64]Metric{},
|
||||
desc: desc,
|
||||
newMetric: func(lvs ...string) Metric {
|
||||
MetricVec: newMetricVec(desc, func(lvs ...string) Metric {
|
||||
return newValue(desc, GaugeValue, 0, lvs...)
|
||||
},
|
||||
},
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -301,13 +301,9 @@ func NewHistogramVec(opts HistogramOpts, labelNames []string) *HistogramVec {
|
|||
opts.ConstLabels,
|
||||
)
|
||||
return &HistogramVec{
|
||||
MetricVec: MetricVec{
|
||||
children: map[uint64]Metric{},
|
||||
desc: desc,
|
||||
newMetric: func(lvs ...string) Metric {
|
||||
MetricVec: newMetricVec(desc, func(lvs ...string) Metric {
|
||||
return newHistogram(desc, opts, lvs...)
|
||||
},
|
||||
},
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -404,13 +404,9 @@ func NewSummaryVec(opts SummaryOpts, labelNames []string) *SummaryVec {
|
|||
opts.ConstLabels,
|
||||
)
|
||||
return &SummaryVec{
|
||||
MetricVec: MetricVec{
|
||||
children: map[uint64]Metric{},
|
||||
desc: desc,
|
||||
newMetric: func(lvs ...string) Metric {
|
||||
MetricVec: newMetricVec(desc, func(lvs ...string) Metric {
|
||||
return newSummary(desc, opts, lvs...)
|
||||
},
|
||||
},
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -70,13 +70,9 @@ func NewUntypedVec(opts UntypedOpts, labelNames []string) *UntypedVec {
|
|||
opts.ConstLabels,
|
||||
)
|
||||
return &UntypedVec{
|
||||
MetricVec: MetricVec{
|
||||
children: map[uint64]Metric{},
|
||||
desc: desc,
|
||||
newMetric: func(lvs ...string) Metric {
|
||||
MetricVec: newMetricVec(desc, func(lvs ...string) Metric {
|
||||
return newValue(desc, UntypedValue, 0, lvs...)
|
||||
},
|
||||
},
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,16 @@ type MetricVec struct {
|
|||
newMetric func(labelValues ...string) Metric
|
||||
}
|
||||
|
||||
// newMetricVec returns an initialized MetricVec. The concrete value is
|
||||
// returned for embedding into another struct.
|
||||
func newMetricVec(desc *Desc, newMetric func(lvs ...string) Metric) MetricVec {
|
||||
return MetricVec{
|
||||
children: map[uint64]Metric{},
|
||||
desc: desc,
|
||||
newMetric: newMetric,
|
||||
}
|
||||
}
|
||||
|
||||
// Describe implements Collector. The length of the returned slice
|
||||
// is always one.
|
||||
func (m *MetricVec) Describe(ch chan<- *Desc) {
|
||||
|
|
|
@ -14,18 +14,12 @@
|
|||
package prometheus
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
desc := NewDesc("test", "helpless", []string{"l1", "l2"}, nil)
|
||||
vec := MetricVec{
|
||||
children: map[uint64]Metric{},
|
||||
desc: desc,
|
||||
newMetric: func(lvs ...string) Metric {
|
||||
return newValue(desc, UntypedValue, 0, lvs...)
|
||||
},
|
||||
}
|
||||
vec := newUntypedMetricVec("test", "helpless", []string{"l1", "l2"})
|
||||
|
||||
if got, want := vec.Delete(Labels{"l1": "v1", "l2": "v2"}), false; got != want {
|
||||
t.Errorf("got %v, want %v", got, want)
|
||||
|
@ -57,14 +51,7 @@ func TestDelete(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDeleteLabelValues(t *testing.T) {
|
||||
desc := NewDesc("test", "helpless", []string{"l1", "l2"}, nil)
|
||||
vec := MetricVec{
|
||||
children: map[uint64]Metric{},
|
||||
desc: desc,
|
||||
newMetric: func(lvs ...string) Metric {
|
||||
return newValue(desc, UntypedValue, 0, lvs...)
|
||||
},
|
||||
}
|
||||
vec := newUntypedMetricVec("test", "helpless", []string{"l1", "l2"})
|
||||
|
||||
if got, want := vec.DeleteLabelValues("v1", "v2"), false; got != want {
|
||||
t.Errorf("got %v, want %v", got, want)
|
||||
|
@ -86,3 +73,77 @@ func TestDeleteLabelValues(t *testing.T) {
|
|||
t.Errorf("got %v, want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func newUntypedMetricVec(name, help string, labels []string) *MetricVec {
|
||||
desc := NewDesc("test", "helpless", labels, nil)
|
||||
vec := newMetricVec(desc, func(lvs ...string) Metric {
|
||||
return newValue(desc, UntypedValue, 0, lvs...)
|
||||
})
|
||||
return &vec
|
||||
}
|
||||
|
||||
func BenchmarkMetricVecWithLabelValuesBasic(B *testing.B) {
|
||||
benchmarkMetricVecWithLabelValues(B, map[string][]string{
|
||||
"l1": []string{"onevalue"},
|
||||
"l2": []string{"twovalue"},
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkMetricVecWithLabelValues2Keys10ValueCardinality(B *testing.B) {
|
||||
benchmarkMetricVecWithLabelValuesCardinality(B, 2, 10)
|
||||
}
|
||||
|
||||
func BenchmarkMetricVecWithLabelValues4Keys10ValueCardinality(B *testing.B) {
|
||||
benchmarkMetricVecWithLabelValuesCardinality(B, 4, 10)
|
||||
}
|
||||
|
||||
func BenchmarkMetricVecWithLabelValues2Keys100ValueCardinality(B *testing.B) {
|
||||
benchmarkMetricVecWithLabelValuesCardinality(B, 2, 100)
|
||||
}
|
||||
|
||||
func BenchmarkMetricVecWithLabelValues10Keys100ValueCardinality(B *testing.B) {
|
||||
benchmarkMetricVecWithLabelValuesCardinality(B, 10, 100)
|
||||
}
|
||||
|
||||
func BenchmarkMetricVecWithLabelValues10Keys1000ValueCardinality(B *testing.B) {
|
||||
benchmarkMetricVecWithLabelValuesCardinality(B, 10, 1000)
|
||||
}
|
||||
|
||||
func benchmarkMetricVecWithLabelValuesCardinality(B *testing.B, nkeys, nvalues int) {
|
||||
labels := map[string][]string{}
|
||||
|
||||
for i := 0; i < nkeys; i++ {
|
||||
var (
|
||||
k = fmt.Sprintf("key-%v", i)
|
||||
vs = make([]string, 0, nvalues)
|
||||
)
|
||||
for j := 0; j < nvalues; j++ {
|
||||
vs = append(vs, fmt.Sprintf("value-%v", j))
|
||||
}
|
||||
labels[k] = vs
|
||||
}
|
||||
|
||||
benchmarkMetricVecWithLabelValues(B, labels)
|
||||
}
|
||||
|
||||
func benchmarkMetricVecWithLabelValues(B *testing.B, labels map[string][]string) {
|
||||
var keys []string
|
||||
for k := range labels { // map order dependent, who cares though
|
||||
keys = append(keys, k)
|
||||
}
|
||||
|
||||
values := make([]string, len(labels)) // value cache for permutations
|
||||
vec := newUntypedMetricVec("test", "helpless", keys)
|
||||
|
||||
B.ReportAllocs()
|
||||
B.ResetTimer()
|
||||
for i := 0; i < B.N; i++ {
|
||||
// varies input across provide map entries based on key size.
|
||||
for j, k := range keys {
|
||||
candidates := labels[k]
|
||||
values[j] = candidates[i%len(candidates)]
|
||||
}
|
||||
|
||||
vec.WithLabelValues(values...)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue