From 0bb55883865fb87efb37760768d03d7576dc6547 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Tue, 12 Mar 2024 11:34:03 +0000 Subject: [PATCH] labels: optimize String method (#13673) Use a stack buffer to reduce memory allocations. `Write(AppendQuote(AvailableBuffer` does not allocate or copy when the buffer has sufficient space. Also add a benchmark, with some refactoring. Signed-off-by: Bryan Boreham --- model/labels/labels_common.go | 5 ++-- model/labels/labels_test.go | 46 ++++++++++++++++------------------- 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/model/labels/labels_common.go b/model/labels/labels_common.go index 4c4a87e87..f46321c97 100644 --- a/model/labels/labels_common.go +++ b/model/labels/labels_common.go @@ -39,7 +39,8 @@ type Label struct { } func (ls Labels) String() string { - var b bytes.Buffer + var bytea [1024]byte // On stack to avoid memory allocation while building the output. + b := bytes.NewBuffer(bytea[:0]) b.WriteByte('{') i := 0 @@ -50,7 +51,7 @@ func (ls Labels) String() string { } b.WriteString(l.Name) b.WriteByte('=') - b.WriteString(strconv.Quote(l.Value)) + b.Write(strconv.AppendQuote(b.AvailableBuffer(), l.Value)) i++ }) b.WriteByte('}') diff --git a/model/labels/labels_test.go b/model/labels/labels_test.go index c2ac6d63a..49b4b4e67 100644 --- a/model/labels/labels_test.go +++ b/model/labels/labels_test.go @@ -43,6 +43,13 @@ func TestLabels_String(t *testing.T) { } } +func BenchmarkString(b *testing.B) { + ls := New(benchmarkLabels...) + for i := 0; i < b.N; i++ { + _ = ls.String() + } +} + func TestLabels_MatchLabels(t *testing.T) { labels := FromStrings( "__name__", "ALERTS", @@ -785,24 +792,24 @@ func BenchmarkLabels_Hash(b *testing.B) { } } -func BenchmarkBuilder(b *testing.B) { - m := []Label{ - {"job", "node"}, - {"instance", "123.123.1.211:9090"}, - {"path", "/api/v1/namespaces//deployments/"}, - {"method", "GET"}, - {"namespace", "system"}, - {"status", "500"}, - {"prometheus", "prometheus-core-1"}, - {"datacenter", "eu-west-1"}, - {"pod_name", "abcdef-99999-defee"}, - } +var benchmarkLabels = []Label{ + {"job", "node"}, + {"instance", "123.123.1.211:9090"}, + {"path", "/api/v1/namespaces//deployments/"}, + {"method", "GET"}, + {"namespace", "system"}, + {"status", "500"}, + {"prometheus", "prometheus-core-1"}, + {"datacenter", "eu-west-1"}, + {"pod_name", "abcdef-99999-defee"}, +} +func BenchmarkBuilder(b *testing.B) { var l Labels builder := NewBuilder(EmptyLabels()) for i := 0; i < b.N; i++ { builder.Reset(EmptyLabels()) - for _, l := range m { + for _, l := range benchmarkLabels { builder.Set(l.Name, l.Value) } l = builder.Labels() @@ -811,18 +818,7 @@ func BenchmarkBuilder(b *testing.B) { } func BenchmarkLabels_Copy(b *testing.B) { - m := map[string]string{ - "job": "node", - "instance": "123.123.1.211:9090", - "path": "/api/v1/namespaces//deployments/", - "method": "GET", - "namespace": "system", - "status": "500", - "prometheus": "prometheus-core-1", - "datacenter": "eu-west-1", - "pod_name": "abcdef-99999-defee", - } - l := FromMap(m) + l := New(benchmarkLabels...) for i := 0; i < b.N; i++ { l = l.Copy()