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>
pull/12956/head
Oleg Zaytsev 1 year ago committed by GitHub
parent 5bd8c8c561
commit fe90dcccff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

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

@ -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) { func BenchmarkListPostings(b *testing.B) {
const maxCount = 1e6 const maxCount = 1e6
input := make([]storage.SeriesRef, maxCount) input := make([]storage.SeriesRef, maxCount)

Loading…
Cancel
Save