From 4931983ca9a58bd16038cf5f32d6cadb0435402f Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Tue, 3 Jan 2023 15:07:22 +0000 Subject: [PATCH 1/2] tsdb/index: make BenchmarkIntersect do work on each loop Previously all the postings constructed were consumed on the first iteration, so subsequent iterations did no work. Signed-off-by: Bryan Boreham --- tsdb/index/postings_test.go | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/tsdb/index/postings_test.go b/tsdb/index/postings_test.go index 75e1677b2b..38736fc6bb 100644 --- a/tsdb/index/postings_test.go +++ b/tsdb/index/postings_test.go @@ -300,14 +300,13 @@ func BenchmarkIntersect(t *testing.B) { d = append(d, storage.SeriesRef(i)) } - i1 := newListPostings(a...) - i2 := newListPostings(b...) - i3 := newListPostings(c...) - i4 := newListPostings(d...) - bench.ResetTimer() bench.ReportAllocs() for i := 0; i < bench.N; i++ { + i1 := newListPostings(a...) + i2 := newListPostings(b...) + i3 := newListPostings(c...) + i4 := newListPostings(d...) if _, err := ExpandPostings(Intersect(i1, i2, i3, i4)); err != nil { bench.Fatal(err) } @@ -330,14 +329,13 @@ func BenchmarkIntersect(t *testing.B) { d = append(d, storage.SeriesRef(i)) } - i1 := newListPostings(a...) - i2 := newListPostings(b...) - i3 := newListPostings(c...) - i4 := newListPostings(d...) - bench.ResetTimer() bench.ReportAllocs() for i := 0; i < bench.N; i++ { + i1 := newListPostings(a...) + i2 := newListPostings(b...) + i3 := newListPostings(c...) + i4 := newListPostings(d...) if _, err := ExpandPostings(Intersect(i1, i2, i3, i4)); err != nil { bench.Fatal(err) } @@ -346,20 +344,28 @@ func BenchmarkIntersect(t *testing.B) { // Many matchers(k >> n). t.Run("ManyPostings", func(bench *testing.B) { - var its []Postings + var lps []*ListPostings + var refs [][]storage.SeriesRef - // 100000 matchers(k=100000). + // Create 100000 matchers(k=100000), making sure all memory allocation is done before starting the loop. for i := 0; i < 100000; i++ { var temp []storage.SeriesRef for j := storage.SeriesRef(1); j < 100; j++ { temp = append(temp, j) } - its = append(its, newListPostings(temp...)) + lps = append(lps, newListPostings(temp...)) + refs = append(refs, temp) } + its := make([]Postings, len(refs)) bench.ResetTimer() bench.ReportAllocs() for i := 0; i < bench.N; i++ { + // Reset the ListPostings to their original values each time round the loop. + for j := range refs { + lps[j].list = refs[j] + its[j] = lps[j] + } if _, err := ExpandPostings(Intersect(its...)); err != nil { bench.Fatal(err) } From 3da2c99ffdf2a6ff8c11e1151e4139f7e83a3f2e Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Tue, 3 Jan 2023 15:08:32 +0000 Subject: [PATCH 2/2] tsdb/index: don't call ExpandPostings in a benchmark This allocates memory for all the returned values, which skews the result. We aren't trying to benchmark `ExpandPostings`, so just step through all the values without storing them to consume them. Signed-off-by: Bryan Boreham --- tsdb/index/postings_test.go | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/tsdb/index/postings_test.go b/tsdb/index/postings_test.go index 38736fc6bb..1b1ecd3c39 100644 --- a/tsdb/index/postings_test.go +++ b/tsdb/index/postings_test.go @@ -280,6 +280,13 @@ func TestMultiIntersect(t *testing.T) { } } +func consumePostings(p Postings) error { + for p.Next() { + p.At() + } + return p.Err() +} + func BenchmarkIntersect(t *testing.B) { t.Run("LongPostings1", func(bench *testing.B) { var a, b, c, d []storage.SeriesRef @@ -307,7 +314,7 @@ func BenchmarkIntersect(t *testing.B) { i2 := newListPostings(b...) i3 := newListPostings(c...) i4 := newListPostings(d...) - if _, err := ExpandPostings(Intersect(i1, i2, i3, i4)); err != nil { + if err := consumePostings(Intersect(i1, i2, i3, i4)); err != nil { bench.Fatal(err) } } @@ -336,7 +343,7 @@ func BenchmarkIntersect(t *testing.B) { i2 := newListPostings(b...) i3 := newListPostings(c...) i4 := newListPostings(d...) - if _, err := ExpandPostings(Intersect(i1, i2, i3, i4)); err != nil { + if err := consumePostings(Intersect(i1, i2, i3, i4)); err != nil { bench.Fatal(err) } } @@ -366,7 +373,7 @@ func BenchmarkIntersect(t *testing.B) { lps[j].list = refs[j] its[j] = lps[j] } - if _, err := ExpandPostings(Intersect(its...)); err != nil { + if err := consumePostings(Intersect(its...)); err != nil { bench.Fatal(err) } }