diff --git a/model/labels/labels.go b/model/labels/labels.go index 18b8f8dc6..056bc6374 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 57d8236a5..815e263ba 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 bufSize := len(b.base.data) + labelsSize(b.add) @@ -754,7 +754,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. diff --git a/model/labels/labels_test.go b/model/labels/labels_test.go index 1902f2f71..4832be337 100644 --- a/model/labels/labels_test.go +++ b/model/labels/labels_test.go @@ -696,6 +696,31 @@ 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 l Labels + builder := NewBuilder(EmptyLabels()) + for i := 0; i < b.N; i++ { + builder.Reset(EmptyLabels()) + for _, l := range m { + builder.Set(l.Name, l.Value) + } + l = builder.Labels(EmptyLabels()) + } + require.Equal(b, 9, l.Len()) +} + func BenchmarkLabels_Copy(b *testing.B) { m := map[string]string{ "job": "node",