github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/colexec/group/group_bench_test.go (about) 1 // Copyright 2021 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package group 16 17 import ( 18 "encoding/json" 19 "testing" 20 "time" 21 22 "github.com/matrixorigin/matrixone/pkg/common/mpool" 23 "github.com/matrixorigin/matrixone/pkg/container/index" 24 "github.com/matrixorigin/matrixone/pkg/container/types" 25 "github.com/matrixorigin/matrixone/pkg/container/vector" 26 "github.com/matrixorigin/matrixone/pkg/pb/plan" 27 "github.com/matrixorigin/matrixone/pkg/sql/colexec/agg" 28 "github.com/matrixorigin/matrixone/pkg/testutil" 29 "github.com/stretchr/testify/require" 30 ) 31 32 const ( 33 benchFlag = false 34 benchCardinality = 1024 35 36 benchTargetRows = 5_000 37 ) 38 39 var ( 40 benchGroupData []string 41 benchGroupIndex *index.LowCardinalityIndex 42 ) 43 44 func init() { 45 if !benchFlag { 46 return 47 } 48 49 benchGroupData = testutil.MakeRandomStrings(benchCardinality, benchTargetRows) 50 51 var err error 52 if benchGroupIndex, err = initBenchIndex(benchGroupData); err != nil { 53 panic(err) 54 } 55 } 56 57 func initBenchIndex(values []string) (*index.LowCardinalityIndex, error) { 58 var err error 59 m := mpool.MustNewZero() 60 v := testutil.NewVector(len(values), types.T_varchar.ToType(), m, false, values) 61 idx, err := index.New(v.Typ, m) 62 if err != nil { 63 return nil, err 64 } 65 if err = idx.InsertBatch(v); err != nil { 66 return nil, err 67 } 68 return idx, nil 69 } 70 71 func TestGroupPerf(t *testing.T) { 72 if !benchFlag { 73 t.Log("benchmark flag is turned off...") 74 return 75 } 76 77 const testCnt = 10 78 79 metricMp := map[string][]int64{ 80 "totalCost": make([]int64, testCnt), 81 "constructGroupDataCost": make([]int64, testCnt), 82 "groupbyCost": make([]int64, testCnt), 83 } 84 avgMp := map[string]int64{ 85 "totalCost": 0, 86 "constructGroupDataCost": 0, 87 "groupbyCost": 0, 88 } 89 90 //---------------- 91 // common group by 92 //---------------- 93 { 94 t.Log("---------- test common group by performance ----------") 95 for i := 0; i < testCnt; i++ { 96 mockTimingCase(t, metricMp, i, nil) 97 } 98 99 metric, err := json.Marshal(metricMp) 100 require.NoError(t, err) 101 t.Logf("common group by performance metric: \n%s\n", string(metric)) 102 103 avg := calcAvg(t, testCnt, metricMp, avgMp) 104 t.Logf("common group by performance average: \n%s\n", avg) 105 } 106 107 t.Logf("\n") 108 109 //------------------------- 110 // low cardinality group by 111 //------------------------- 112 { 113 t.Log("---------- test low cardinality group by performance ----------") 114 for i := 0; i < testCnt; i++ { 115 mockTimingCase(t, metricMp, i, benchGroupIndex.Dup()) 116 } 117 118 metric, err := json.Marshal(metricMp) 119 require.NoError(t, err) 120 t.Logf("low cardinality group by performance metric: \n%s\n", string(metric)) 121 122 avg := calcAvg(t, testCnt, metricMp, avgMp) 123 t.Logf("low cardinality group by performance average: \n%s\n", avg) 124 } 125 } 126 127 func mockTimingCase(t *testing.T, metricMp map[string][]int64, pos int, idx *index.LowCardinalityIndex) { 128 totalStart := time.Now().UnixNano() 129 // SELECT COUNT(*) FROM t GROUP BY t.col 130 tc := newTestCase([]bool{false}, []types.Type{{Oid: types.T_varchar}}, 131 []*plan.Expr{newExpression(0)}, []agg.Aggregate{{Op: 5, E: newExpression(0)}}) 132 133 // construct group data part 134 constructGroupDataStart := time.Now().UnixNano() 135 v := testutil.NewVector(len(benchGroupData), types.T_varchar.ToType(), tc.proc.Mp(), false, benchGroupData) 136 if idx != nil { 137 v.SetIndex(idx) 138 } 139 constructGroupDataEnd := time.Now().UnixNano() 140 metricMp["constructGroupDataCost"][pos] = constructGroupDataEnd - constructGroupDataStart 141 142 // group by part 143 groupbyStart := time.Now().UnixNano() 144 err := Prepare(tc.proc, tc.arg) 145 require.NoError(t, err) 146 tc.proc.Reg.InputBatch = testutil.NewBatchWithVectors([]*vector.Vector{v}, nil) 147 _, err = Call(0, tc.proc, tc.arg, false, false) 148 require.NoError(t, err) 149 groupbyEnd := time.Now().UnixNano() 150 metricMp["groupbyCost"][pos] = groupbyEnd - groupbyStart 151 152 if tc.proc.Reg.InputBatch != nil { 153 tc.proc.Reg.InputBatch.Clean(tc.proc.Mp()) 154 } 155 156 totalEnd := time.Now().UnixNano() 157 metricMp["totalCost"][pos] = totalEnd - totalStart 158 } 159 160 func calcAvg(t *testing.T, cnt int64, perf map[string][]int64, avg map[string]int64) string { 161 for k, data := range perf { 162 sum := int64(0) 163 for _, v := range data { 164 sum += v 165 } 166 avg[k] = sum / cnt 167 } 168 169 res, err := json.Marshal(avg) 170 require.NoError(t, err) 171 return string(res) 172 }