Skip to content

Commit 36d0bf9

Browse files
authored
labelset: optimise String() function (#590)
Build the output in a `bytes.Buffer` to avoid creating small strings which are passed to `Join`. Use stack arrays to avoid allocations for small buffers, and `AppendQuote`/`AvailableBuffer` avoids allocating and copying in the case that buffer space is sufficient. Signed-off-by: Bryan Boreham <[email protected]>
1 parent e8be06d commit 36d0bf9

File tree

1 file changed

+20
-8
lines changed

1 file changed

+20
-8
lines changed

Diff for: model/labelset.go

+20-8
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@
1414
package model
1515

1616
import (
17+
"bytes"
1718
"encoding/json"
1819
"fmt"
20+
"slices"
1921
"sort"
20-
"strings"
22+
"strconv"
2123
)
2224

2325
// A LabelSet is a collection of LabelName and LabelValue pairs. The LabelSet
@@ -129,17 +131,27 @@ func (l LabelSet) Merge(other LabelSet) LabelSet {
129131
return result
130132
}
131133

134+
// String will look like `{foo="bar", more="less"}`. Names are sorted alphabetically.
132135
func (l LabelSet) String() string {
133-
labelNames := make([]string, 0, len(l))
136+
var lna [32]LabelName // On stack to avoid memory allocation for sorting names.
137+
labelNames := lna[:0]
134138
for name := range l {
135-
labelNames = append(labelNames, string(name))
139+
labelNames = append(labelNames, name)
136140
}
137-
sort.Strings(labelNames)
138-
lstrs := make([]string, 0, len(l))
139-
for _, name := range labelNames {
140-
lstrs = append(lstrs, fmt.Sprintf("%s=%q", name, l[LabelName(name)]))
141+
slices.Sort(labelNames)
142+
var bytea [1024]byte // On stack to avoid memory allocation while building the output.
143+
b := bytes.NewBuffer(bytea[:0])
144+
b.WriteByte('{')
145+
for i, name := range labelNames {
146+
if i > 0 {
147+
b.WriteString(", ")
148+
}
149+
b.WriteString(string(name))
150+
b.WriteByte('=')
151+
b.Write(strconv.AppendQuote(b.AvailableBuffer(), string(l[name])))
141152
}
142-
return fmt.Sprintf("{%s}", strings.Join(lstrs, ", "))
153+
b.WriteByte('}')
154+
return b.String()
143155
}
144156

145157
// Fingerprint returns the LabelSet's fingerprint.

0 commit comments

Comments
 (0)