Reduce constrainLabels allocations (#1272)
* Add bench Signed-off-by: Bulat Khasanov <afti@yandex.ru> * Reduce constrainLabels allocations Signed-off-by: Bulat Khasanov <afti@yandex.ru> --------- Signed-off-by: Bulat Khasanov <afti@yandex.ru>
This commit is contained in:
parent
8840afcfc2
commit
a09a1d34cb
|
@ -20,6 +20,24 @@ import (
|
||||||
"github.com/prometheus/common/model"
|
"github.com/prometheus/common/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var labelsPool = &sync.Pool{
|
||||||
|
New: func() interface{} {
|
||||||
|
return make(Labels)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func getLabelsFromPool() Labels {
|
||||||
|
return labelsPool.Get().(Labels)
|
||||||
|
}
|
||||||
|
|
||||||
|
func putLabelsToPool(labels Labels) {
|
||||||
|
for k := range labels {
|
||||||
|
delete(labels, k)
|
||||||
|
}
|
||||||
|
|
||||||
|
labelsPool.Put(labels)
|
||||||
|
}
|
||||||
|
|
||||||
// MetricVec is a Collector to bundle metrics of the same name that differ in
|
// MetricVec is a Collector to bundle metrics of the same name that differ in
|
||||||
// their label values. MetricVec is not used directly but as a building block
|
// their label values. MetricVec is not used directly but as a building block
|
||||||
// for implementations of vectors of a given metric type, like GaugeVec,
|
// for implementations of vectors of a given metric type, like GaugeVec,
|
||||||
|
@ -93,6 +111,8 @@ func (m *MetricVec) DeleteLabelValues(lvs ...string) bool {
|
||||||
// there for pros and cons of the two methods.
|
// there for pros and cons of the two methods.
|
||||||
func (m *MetricVec) Delete(labels Labels) bool {
|
func (m *MetricVec) Delete(labels Labels) bool {
|
||||||
labels = constrainLabels(m.desc, labels)
|
labels = constrainLabels(m.desc, labels)
|
||||||
|
defer putLabelsToPool(labels)
|
||||||
|
|
||||||
h, err := m.hashLabels(labels)
|
h, err := m.hashLabels(labels)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
|
@ -109,6 +129,8 @@ func (m *MetricVec) Delete(labels Labels) bool {
|
||||||
// To match curried labels with DeletePartialMatch, it must be called on the base vector.
|
// To match curried labels with DeletePartialMatch, it must be called on the base vector.
|
||||||
func (m *MetricVec) DeletePartialMatch(labels Labels) int {
|
func (m *MetricVec) DeletePartialMatch(labels Labels) int {
|
||||||
labels = constrainLabels(m.desc, labels)
|
labels = constrainLabels(m.desc, labels)
|
||||||
|
defer putLabelsToPool(labels)
|
||||||
|
|
||||||
return m.metricMap.deleteByLabels(labels, m.curry)
|
return m.metricMap.deleteByLabels(labels, m.curry)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,6 +251,8 @@ func (m *MetricVec) GetMetricWithLabelValues(lvs ...string) (Metric, error) {
|
||||||
// for example GaugeVec.
|
// for example GaugeVec.
|
||||||
func (m *MetricVec) GetMetricWith(labels Labels) (Metric, error) {
|
func (m *MetricVec) GetMetricWith(labels Labels) (Metric, error) {
|
||||||
labels = constrainLabels(m.desc, labels)
|
labels = constrainLabels(m.desc, labels)
|
||||||
|
defer putLabelsToPool(labels)
|
||||||
|
|
||||||
h, err := m.hashLabels(labels)
|
h, err := m.hashLabels(labels)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -647,15 +671,16 @@ func inlineLabelValues(lvs []string, curry []curriedLabelValue) []string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func constrainLabels(desc *Desc, labels Labels) Labels {
|
func constrainLabels(desc *Desc, labels Labels) Labels {
|
||||||
constrainedValues := make(Labels, len(labels))
|
constrainedLabels := getLabelsFromPool()
|
||||||
for l, v := range labels {
|
for l, v := range labels {
|
||||||
if i, ok := indexOf(l, desc.variableLabels.labelNames()); ok {
|
if i, ok := indexOf(l, desc.variableLabels.labelNames()); ok {
|
||||||
constrainedValues[l] = desc.variableLabels[i].Constrain(v)
|
v = desc.variableLabels[i].Constrain(v)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
constrainedValues[l] = v
|
|
||||||
|
constrainedLabels[l] = v
|
||||||
}
|
}
|
||||||
return constrainedValues
|
|
||||||
|
return constrainedLabels
|
||||||
}
|
}
|
||||||
|
|
||||||
func constrainLabelValues(desc *Desc, lvs []string, curry []curriedLabelValue) []string {
|
func constrainLabelValues(desc *Desc, lvs []string, curry []curriedLabelValue) []string {
|
||||||
|
|
|
@ -904,6 +904,13 @@ func testConstrainedCurryVec(t *testing.T, vec *CounterVec, constraint func(stri
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkMetricVecWithBasic(b *testing.B) {
|
||||||
|
benchmarkMetricVecWith(b, Labels{
|
||||||
|
"l1": "onevalue",
|
||||||
|
"l2": "twovalue",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkMetricVecWithLabelValuesBasic(b *testing.B) {
|
func BenchmarkMetricVecWithLabelValuesBasic(b *testing.B) {
|
||||||
benchmarkMetricVecWithLabelValues(b, map[string][]string{
|
benchmarkMetricVecWithLabelValues(b, map[string][]string{
|
||||||
"l1": {"onevalue"},
|
"l1": {"onevalue"},
|
||||||
|
@ -948,6 +955,27 @@ func benchmarkMetricVecWithLabelValuesCardinality(b *testing.B, nkeys, nvalues i
|
||||||
benchmarkMetricVecWithLabelValues(b, labels)
|
benchmarkMetricVecWithLabelValues(b, labels)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func benchmarkMetricVecWith(b *testing.B, labels map[string]string) {
|
||||||
|
var keys []string
|
||||||
|
for k := range labels {
|
||||||
|
keys = append(keys, k)
|
||||||
|
}
|
||||||
|
|
||||||
|
vec := NewGaugeVec(
|
||||||
|
GaugeOpts{
|
||||||
|
Name: "test",
|
||||||
|
Help: "helpless",
|
||||||
|
},
|
||||||
|
keys,
|
||||||
|
)
|
||||||
|
|
||||||
|
b.ReportAllocs()
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
vec.With(labels)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func benchmarkMetricVecWithLabelValues(b *testing.B, labels map[string][]string) {
|
func benchmarkMetricVecWithLabelValues(b *testing.B, labels map[string][]string) {
|
||||||
var keys []string
|
var keys []string
|
||||||
for k := range labels { // Map order dependent, who cares though.
|
for k := range labels { // Map order dependent, who cares though.
|
||||||
|
|
Loading…
Reference in New Issue