From 38c6d3da9ffb1dbff19edb6ea161b5f30a9b5e8c Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Mon, 6 Mar 2023 18:22:49 +0000 Subject: [PATCH] labels: use slices.Sort for better performance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The difference is modest, but we've used `slices.Sort` in lots of other places so why not here. name old time/op new time/op delta Builder 1.04µs ± 3% 0.95µs ± 3% -8.27% (p=0.008 n=5+5) name old alloc/op new alloc/op delta Builder 312B ± 0% 288B ± 0% -7.69% (p=0.008 n=5+5) name old allocs/op new allocs/op delta Builder 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.008 n=5+5) Signed-off-by: Bryan Boreham --- model/labels/labels.go | 10 +++++----- model/labels/labels_string.go | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/model/labels/labels.go b/model/labels/labels.go index 18b8f8dc62..056bc63740 100644 --- a/model/labels/labels.go +++ b/model/labels/labels.go @@ -18,11 +18,11 @@ package labels import ( "bytes" "encoding/json" - "sort" "strconv" "github.com/cespare/xxhash/v2" "github.com/prometheus/common/model" + "golang.org/x/exp/slices" ) // Well-known label names used by Prometheus components. @@ -360,7 +360,7 @@ func EmptyLabels() Labels { func New(ls ...Label) Labels { set := make(Labels, 0, len(ls)) set = append(set, ls...) - sort.Sort(set) + slices.SortFunc(set, func(a, b Label) bool { return a.Name < b.Name }) return set } @@ -384,7 +384,7 @@ func FromStrings(ss ...string) Labels { res = append(res, Label{Name: ss[i], Value: ss[i+1]}) } - sort.Sort(res) + slices.SortFunc(res, func(a, b Label) bool { return a.Name < b.Name }) return res } @@ -564,7 +564,7 @@ Outer: } if len(b.add) > 0 { // Base is already in order, so we only need to sort if we add to it. res = append(res, b.add...) - sort.Sort(res) + slices.SortFunc(res, func(a, b Label) bool { return a.Name < b.Name }) } return res } @@ -591,7 +591,7 @@ func (b *ScratchBuilder) Add(name, value string) { // Sort the labels added so far by name. func (b *ScratchBuilder) Sort() { - sort.Sort(b.add) + slices.SortFunc(b.add, func(a, b Label) bool { return a.Name < b.Name }) } // Asssign is for when you already have a Labels which you want this ScratchBuilder to return. diff --git a/model/labels/labels_string.go b/model/labels/labels_string.go index e912882fe3..ccba604ee2 100644 --- a/model/labels/labels_string.go +++ b/model/labels/labels_string.go @@ -19,12 +19,12 @@ import ( "bytes" "encoding/json" "reflect" - "sort" "strconv" "unsafe" "github.com/cespare/xxhash/v2" "github.com/prometheus/common/model" + "golang.org/x/exp/slices" ) // Well-known label names used by Prometheus components. @@ -385,7 +385,7 @@ func yoloBytes(s string) (b []byte) { // New returns a sorted Labels from the given labels. // The caller has to guarantee that all label names are unique. func New(ls ...Label) Labels { - sort.Sort(labelSlice(ls)) + slices.SortFunc(ls, func(a, b Label) bool { return a.Name < b.Name }) size := labelsSize(ls) buf := make([]byte, size) marshalLabelsToSizedBuffer(ls, buf) @@ -411,7 +411,7 @@ func FromStrings(ss ...string) Labels { ls = append(ls, Label{Name: ss[i], Value: ss[i+1]}) } - sort.Sort(labelSlice(ls)) + slices.SortFunc(ls, func(a, b Label) bool { return a.Name < b.Name }) return New(ls...) } @@ -595,8 +595,8 @@ func (b *Builder) Labels(res Labels) Labels { return b.base } - sort.Sort(labelSlice(b.add)) - sort.Strings(b.del) + slices.SortFunc(b.add, func(a, b Label) bool { return a.Name < b.Name }) + slices.Sort(b.del) a, d := 0, 0 buf := make([]byte, 0, len(b.base.data)) // TODO: see if we can re-use the buffer from res. @@ -753,7 +753,7 @@ func (b *ScratchBuilder) Add(name, value string) { // Sort the labels added so far by name. func (b *ScratchBuilder) Sort() { - sort.Sort(labelSlice(b.add)) + slices.SortFunc(b.add, func(a, b Label) bool { return a.Name < b.Name }) } // Asssign is for when you already have a Labels which you want this ScratchBuilder to return.