mirror of
https://github.com/prometheus/prometheus.git
synced 2025-01-27 05:32:27 -08:00
Reduce allocations for queries on HEAD
(#417)
Some benchmarks for HEAD and allocate the correct slice size in LabelValues , we already know what it'll be This is ~15% time improvement, and ~25% allocation improvement: ``` benchmark old ns/op new ns/op delta BenchmarkHeadPostingForMatchers-4 74452 63514 -14.69% benchmark old allocs new allocs delta BenchmarkHeadPostingForMatchers-4 20 13 -35.00% benchmark old bytes new bytes delta BenchmarkHeadPostingForMatchers-4 5425 3137 -42.18% ``` Signed-off-by: Thomas Jackson <jacksontj.89@gmail.com>
This commit is contained in:
parent
18af5763d8
commit
b4132df5f7
5
head.go
5
head.go
|
@ -1014,14 +1014,13 @@ func (h *headIndexReader) LabelValues(names ...string) (index.StringTuples, erro
|
||||||
if len(names) != 1 {
|
if len(names) != 1 {
|
||||||
return nil, errInvalidSize
|
return nil, errInvalidSize
|
||||||
}
|
}
|
||||||
var sl []string
|
|
||||||
|
|
||||||
h.head.symMtx.RLock()
|
h.head.symMtx.RLock()
|
||||||
defer h.head.symMtx.RUnlock()
|
sl := make([]string, 0, len(h.head.values[names[0]]))
|
||||||
|
|
||||||
for s := range h.head.values[names[0]] {
|
for s := range h.head.values[names[0]] {
|
||||||
sl = append(sl, s)
|
sl = append(sl, s)
|
||||||
}
|
}
|
||||||
|
h.head.symMtx.RUnlock()
|
||||||
sort.Strings(sl)
|
sort.Strings(sl)
|
||||||
|
|
||||||
return index.NewStringTuples(sl, len(names))
|
return index.NewStringTuples(sl, len(names))
|
||||||
|
|
59
head_bench_test.go
Normal file
59
head_bench_test.go
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
package tsdb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"sync/atomic"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/prometheus/tsdb/labels"
|
||||||
|
"github.com/prometheus/tsdb/testutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func BenchmarkHeadStripeSeriesCreate(b *testing.B) {
|
||||||
|
// Put a series, select it. GC it and then access it.
|
||||||
|
h, err := NewHead(nil, nil, nil, 1000)
|
||||||
|
testutil.Ok(b, err)
|
||||||
|
defer h.Close()
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
h.getOrCreate(uint64(i), labels.FromStrings("a", strconv.Itoa(i)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkHeadStripeSeriesCreateParallel(b *testing.B) {
|
||||||
|
// Put a series, select it. GC it and then access it.
|
||||||
|
h, err := NewHead(nil, nil, nil, 1000)
|
||||||
|
testutil.Ok(b, err)
|
||||||
|
defer h.Close()
|
||||||
|
|
||||||
|
var count int64
|
||||||
|
|
||||||
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
|
for pb.Next() {
|
||||||
|
i := atomic.AddInt64(&count, 1)
|
||||||
|
h.getOrCreate(uint64(i), labels.FromStrings("a", strconv.Itoa(int(i))))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: generalize benchmark and pass all postings for matchers here
|
||||||
|
func BenchmarkHeadPostingForMatchers(b *testing.B) {
|
||||||
|
// Put a series, select it. GC it and then access it.
|
||||||
|
h, err := NewHead(nil, nil, nil, 1000)
|
||||||
|
testutil.Ok(b, err)
|
||||||
|
defer h.Close()
|
||||||
|
|
||||||
|
// TODO: vary number of series
|
||||||
|
for i := 0; i < 100; i++ {
|
||||||
|
h.getOrCreate(uint64(i), labels.FromStrings("a", strconv.Itoa(i)))
|
||||||
|
}
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
|
||||||
|
all, _ := labels.NewRegexpMatcher("a", ".*")
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_, err := PostingsForMatchers(h.indexRange(0, 1000), all)
|
||||||
|
testutil.Ok(b, err)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue