From 7f2374b703e5ac779cfab3feefb8ade3fbf2487d Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Fri, 30 Sep 2022 15:31:32 +0100 Subject: [PATCH] tsdb: faster postings sort with generic slices.Sort (#11054) Use new experimental package `golang.org/x/exp/slices`. Some of the speedup comes from comparing SeriesRef (which is an int64) directly rather than through an interface `.Less()` call; some comes from exp/slices using "pattern-defeating quicksort(pdqsort)". Signed-off-by: Bryan Boreham Signed-off-by: Bryan Boreham --- go.mod | 1 + go.sum | 2 ++ tsdb/index/postings.go | 12 ++---------- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index 8d693cae65..6e6be80f40 100644 --- a/go.mod +++ b/go.mod @@ -167,6 +167,7 @@ require ( go.opentelemetry.io/otel/metric v0.32.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect + golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect golang.org/x/text v0.3.7 // indirect diff --git a/go.sum b/go.sum index 8d1b6ef975..c765a770a3 100644 --- a/go.sum +++ b/go.sum @@ -915,6 +915,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= +golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= diff --git a/tsdb/index/postings.go b/tsdb/index/postings.go index 8df2bccf67..a9898fc4a2 100644 --- a/tsdb/index/postings.go +++ b/tsdb/index/postings.go @@ -21,6 +21,7 @@ import ( "sync" "github.com/pkg/errors" + "golang.org/x/exp/slices" "github.com/prometheus/prometheus/model/labels" "github.com/prometheus/prometheus/storage" @@ -239,11 +240,9 @@ func (p *MemPostings) EnsureOrder() { for i := 0; i < n; i++ { go func() { - var sortable seriesRefSlice for job := range workc { for _, l := range *job { - sortable = l - sort.Sort(&sortable) + slices.Sort(l) } *job = (*job)[:0] @@ -830,13 +829,6 @@ func (it *bigEndianPostings) Err() error { return nil } -// seriesRefSlice attaches the methods of sort.Interface to []storage.SeriesRef, sorting in increasing order. -type seriesRefSlice []storage.SeriesRef - -func (x seriesRefSlice) Len() int { return len(x) } -func (x seriesRefSlice) Less(i, j int) bool { return x[i] < x[j] } -func (x seriesRefSlice) Swap(i, j int) { x[i], x[j] = x[j], x[i] } - // FindIntersectingPostings checks the intersection of p and candidates[i] for each i in candidates, // if intersection is non empty, then i is added to the indexes returned. // Returned indexes are not sorted.