Revert ListPostings change (#12955)

Reverts change from https://github.com/prometheus/prometheus/pull/12906

The benchmarks show that it's slower when intersecting, which is a
common usage for ListPostings (when intersecting matchers from Head)

(old is before #12906, new is #12906):

                           │     old     │                 new                 │
                           │   sec/op    │   sec/op     vs base                │
Intersect/LongPostings1-16   20.54µ ± 1%   21.11µ ± 1%   +2.76% (p=0.000 n=20)
Intersect/LongPostings2-16   51.03m ± 1%   52.40m ± 2%   +2.69% (p=0.000 n=20)
Intersect/ManyPostings-16    194.2m ± 3%   332.1m ± 1%  +71.00% (p=0.000 n=20)
geomean                      5.882m        7.161m       +21.74%

Signed-off-by: Oleg Zaytsev <mail@olegzaytsev.com>
This commit is contained in:
Oleg Zaytsev 2023-10-09 17:25:18 +02:00 committed by GitHub
parent 5bd8c8c561
commit fe90dcccff
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 15 deletions

View file

@ -748,7 +748,7 @@ func (rp *removedPostings) Err() error {
// ListPostings implements the Postings interface over a plain list.
type ListPostings struct {
list []storage.SeriesRef
pos int
cur storage.SeriesRef
}
func NewListPostings(list []storage.SeriesRef) Postings {
@ -760,34 +760,39 @@ func newListPostings(list ...storage.SeriesRef) *ListPostings {
}
func (it *ListPostings) At() storage.SeriesRef {
return it.list[it.pos-1]
return it.cur
}
func (it *ListPostings) Next() bool {
if it.pos < len(it.list) {
it.pos++
if len(it.list) > 0 {
it.cur = it.list[0]
it.list = it.list[1:]
return true
}
it.cur = 0
return false
}
func (it *ListPostings) Seek(x storage.SeriesRef) bool {
if it.pos == 0 {
it.pos++
}
if it.pos > len(it.list) {
return false
}
// If the current value satisfies, then return.
if it.list[it.pos-1] >= x {
if it.cur >= x {
return true
}
if len(it.list) == 0 {
return false
}
// Do binary search between current position and end.
it.pos = sort.Search(len(it.list[it.pos-1:]), func(i int) bool {
return it.list[i+it.pos-1] >= x
}) + it.pos
return it.pos-1 < len(it.list)
i := sort.Search(len(it.list), func(i int) bool {
return it.list[i] >= x
})
if i < len(it.list) {
it.cur = it.list[i]
it.list = it.list[i+1:]
return true
}
it.list = nil
return false
}
func (it *ListPostings) Err() error {

View file

@ -1242,6 +1242,8 @@ func TestListPostings(t *testing.T) {
})
}
// BenchmarkListPostings benchmarks ListPostings by iterating Next/At sequentially.
// See also BenchmarkIntersect as it performs more `At` calls than `Next` calls when intersecting.
func BenchmarkListPostings(b *testing.B) {
const maxCount = 1e6
input := make([]storage.SeriesRef, maxCount)