From c0a9b87f468be6e209e66c7656847bbbea3a992f Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Thu, 15 Feb 2024 14:30:08 +0200 Subject: [PATCH] lib/mergeset: optimize Set.AddMulti() a bit for len(items) < 10000 This should improve the search speed for time series matching the given label filters --- lib/uint64set/uint64set.go | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/lib/uint64set/uint64set.go b/lib/uint64set/uint64set.go index 37c5417ac7..eb16e38cbe 100644 --- a/lib/uint64set/uint64set.go +++ b/lib/uint64set/uint64set.go @@ -814,21 +814,23 @@ func (b *bucket16) add(x uint16) bool { } func (b *bucket16) addMulti(a []uint64) int { - count := 0 if b.bits == nil { + if b.smallPoolLen + len(a) > len(b.smallPool) { + b.switchSmallPoolToBits() + goto fastPath + } // Slow path - for i, x := range a { - if b.add(uint16(x)) { + count := 0 + for _, x := range a { + if b.addToSmallPool(uint16(x)) { count++ } - if b.bits != nil { - a = a[i+1:] - goto fastPath - } } return count } + fastPath: + count := 0 bits := b.bits for _, x := range a { wordNum, bitMask := getWordNumBitMask(uint16(x)) @@ -850,14 +852,19 @@ func (b *bucket16) addToSmallPool(x uint16) bool { b.smallPoolLen++ return true } + b.switchSmallPoolToBits() + b.add(x) + return true +} + +func (b *bucket16) switchSmallPoolToBits() { + smallPoolLen := b.smallPoolLen b.smallPoolLen = 0 var bits [wordsPerBucket]uint64 b.bits = &bits - for _, v := range sp[:] { + for _, v := range b.smallPool[:smallPoolLen] { b.add(v) } - b.add(x) - return true } func (b *bucket16) has(x uint16) bool {