chore: Add GroupBy benchmark

pull/10616/head
Stuart Carnie 2018-11-20 11:55:04 -07:00
parent 26408dc1fa
commit 7fb015cc7f
No known key found for this signature in database
GPG Key ID: 848D9C9718D78B4F
3 changed files with 185 additions and 0 deletions

View File

@ -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 }

View File

@ -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]
}

View File

@ -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()
}
}