chore: Add GroupBy benchmark
parent
26408dc1fa
commit
7fb015cc7f
|
@ -0,0 +1,59 @@
|
|||
package gen
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
type Sequence interface {
|
||||
Next() bool
|
||||
Value() string
|
||||
Count() int
|
||||
}
|
||||
|
||||
type CounterByteSequence struct {
|
||||
format string
|
||||
nfmt string
|
||||
val string
|
||||
s int
|
||||
v int
|
||||
end int
|
||||
}
|
||||
|
||||
func NewCounterByteSequenceCount(n int) *CounterByteSequence {
|
||||
return NewCounterByteSequence("value%s", 0, n)
|
||||
}
|
||||
|
||||
func NewCounterByteSequence(format string, start, end int) *CounterByteSequence {
|
||||
s := &CounterByteSequence{
|
||||
format: format,
|
||||
nfmt: fmt.Sprintf("%%0%dd", int(math.Ceil(math.Log10(float64(end))))),
|
||||
s: start,
|
||||
v: start,
|
||||
end: end,
|
||||
}
|
||||
s.update()
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *CounterByteSequence) Next() bool {
|
||||
s.v++
|
||||
if s.v >= s.end {
|
||||
s.v = s.s
|
||||
}
|
||||
s.update()
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *CounterByteSequence) update() {
|
||||
s.val = fmt.Sprintf(s.format, fmt.Sprintf(s.nfmt, s.v))
|
||||
}
|
||||
|
||||
func (s *CounterByteSequence) Count() int { return s.end - s.s }
|
||||
func (s *CounterByteSequence) Value() string { return s.val }
|
||||
|
||||
type ConstantStringSequence string
|
||||
|
||||
func (ConstantStringSequence) Next() bool { return true }
|
||||
func (s ConstantStringSequence) Value() string { return string(s) }
|
||||
func (ConstantStringSequence) Count() int { return 1 }
|
|
@ -0,0 +1,93 @@
|
|||
package gen
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"sort"
|
||||
|
||||
"github.com/influxdata/influxdb/models"
|
||||
)
|
||||
|
||||
type TagsSequence interface {
|
||||
Next() bool
|
||||
Value() models.Tags
|
||||
Count() int
|
||||
}
|
||||
|
||||
type TagsValuesSequence struct {
|
||||
tags models.Tags
|
||||
vals []Sequence
|
||||
n int
|
||||
max int
|
||||
}
|
||||
|
||||
func NewTagsValuesSequenceKeysValues(keys []string, vals []Sequence) *TagsValuesSequence {
|
||||
tm := make(map[string]string, len(keys))
|
||||
for _, k := range keys {
|
||||
tm[k] = ""
|
||||
}
|
||||
|
||||
count := 1
|
||||
for i := range vals {
|
||||
count *= vals[i].Count()
|
||||
}
|
||||
|
||||
// models.Tags are ordered, so ensure vals are ordered with respect to keys
|
||||
sort.Sort(keyValues{keys, vals})
|
||||
|
||||
return &TagsValuesSequence{
|
||||
tags: models.NewTags(tm),
|
||||
vals: vals,
|
||||
max: count,
|
||||
}
|
||||
}
|
||||
|
||||
func NewTagsValuesSequenceValues(prefix string, vals []Sequence) *TagsValuesSequence {
|
||||
keys := make([]string, len(vals))
|
||||
// max tag width
|
||||
tw := int(math.Ceil(math.Log10(float64(len(vals)))))
|
||||
tf := fmt.Sprintf("%s%%0%dd", prefix, tw)
|
||||
for i := range vals {
|
||||
keys[i] = fmt.Sprintf(tf, i)
|
||||
}
|
||||
return NewTagsValuesSequenceKeysValues(keys, vals)
|
||||
}
|
||||
|
||||
func (s *TagsValuesSequence) Next() bool {
|
||||
if s.n >= s.max {
|
||||
return false
|
||||
}
|
||||
|
||||
for i := range s.vals {
|
||||
s.tags[i].Value = []byte(s.vals[i].Value())
|
||||
}
|
||||
|
||||
s.n++
|
||||
i := s.n
|
||||
for j := len(s.vals) - 1; j >= 0; j-- {
|
||||
v := s.vals[j]
|
||||
v.Next()
|
||||
c := v.Count()
|
||||
if r := i % c; r != 0 {
|
||||
break
|
||||
}
|
||||
i /= c
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *TagsValuesSequence) Value() models.Tags { return s.tags }
|
||||
func (s *TagsValuesSequence) Count() int { return s.max }
|
||||
|
||||
type keyValues struct {
|
||||
keys []string
|
||||
vals []Sequence
|
||||
}
|
||||
|
||||
func (k keyValues) Len() int { return len(k.keys) }
|
||||
func (k keyValues) Less(i, j int) bool { return k.keys[i] < k.keys[j] }
|
||||
func (k keyValues) Swap(i, j int) {
|
||||
k.keys[i], k.keys[j] = k.keys[j], k.keys[i]
|
||||
k.vals[i], k.vals[j] = k.vals[j], k.vals[i]
|
||||
}
|
|
@ -307,3 +307,36 @@ func (s *sliceSeriesCursor) Next() *reads.SeriesRow {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func BenchmarkNewGroupResultSet_GroupBy(b *testing.B) {
|
||||
card := []int{10, 10, 10}
|
||||
vals := make([]gen.Sequence, len(card))
|
||||
for i := range card {
|
||||
vals[i] = gen.NewCounterByteSequenceCount(card[i])
|
||||
}
|
||||
|
||||
tags := gen.NewTagsValuesSequenceValues("tag", vals)
|
||||
rows := make([]reads.SeriesRow, tags.Count())
|
||||
for i := range rows {
|
||||
tags.Next()
|
||||
t := tags.Value().Clone()
|
||||
rows[i].SeriesTags = t
|
||||
rows[i].Tags = t
|
||||
rows[i].Name = []byte("m0")
|
||||
}
|
||||
|
||||
cur := &sliceSeriesCursor{rows: rows}
|
||||
newCursor := func() (reads.SeriesCursor, error) {
|
||||
cur.i = 0
|
||||
return cur, nil
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
b.ReportAllocs()
|
||||
for i := 0; i < b.N; i++ {
|
||||
var hints datatypes.HintFlags
|
||||
hints.SetHintSchemaAllTime()
|
||||
rs := reads.NewGroupResultSet(context.Background(), &datatypes.ReadRequest{Group: datatypes.GroupBy, GroupKeys: []string{"tag2"}, Hints: hints}, newCursor)
|
||||
rs.Close()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue