github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/performance/benchmarks/results.go (about) 1 // Copyright 2019 Dolthub, Inc. 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 main 16 17 import ( 18 "fmt" 19 "io" 20 "log" 21 "os" 22 "path/filepath" 23 "testing" 24 "time" 25 26 "github.com/dolthub/dolt/go/libraries/utils/filesys" 27 "github.com/dolthub/dolt/go/store/types" 28 ) 29 30 type result struct { 31 name string 32 format string 33 rows int 34 columns int 35 br testing.BenchmarkResult 36 } 37 38 // RDSImpl is a Dataset containing results of benchmarking 39 type RSImpl struct { 40 // Schema defines the structure of the Dataset 41 Schema *SeedSchema 42 43 // Results are results of benchmarking 44 Results []result 45 46 // TableName is the name of the results table 47 TableName string 48 49 // w is the writer where the results will be written 50 w io.Writer 51 } 52 53 // NewRSImpl creates a new RSImpl 54 func NewRSImpl(w io.Writer, sch *SeedSchema, results []result, tableName string) *RSImpl { 55 return &RSImpl{ 56 Schema: sch, 57 Results: results, 58 TableName: tableName, 59 w: w, 60 } 61 } 62 63 // GenerateData writes the results to a io.Writer 64 func (rds *RSImpl) GenerateData() { 65 writeResultsToWriter(rds.w, rds.Results, rds.Schema.Columns, rds.TableName, rds.Schema.FileFormatExt) 66 } 67 68 // Change returns a DataSet that is a mutation of this Dataset by the given percentage 69 func (rds *RSImpl) Change(pct float32) Dataset { 70 // TODO 71 return &RSImpl{} 72 } 73 74 func writeResultsToWriter(wc io.Writer, results []result, cols []*SeedColumn, tableName, format string) { 75 switch format { 76 case csvExt: 77 generateCSVResults(wc, results, cols, tableName, format) 78 default: 79 log.Fatalf("cannot generate results data, file format %s unsupported \n", format) 80 } 81 } 82 83 func generateCSVResults(wc io.Writer, results []result, cols []*SeedColumn, tableName, format string) { 84 header := makeCSVHeaderStr(cols, tableName, format) 85 86 _, err := wc.Write([]byte(header)) 87 if err != nil { 88 log.Fatal(err) 89 } 90 91 for i, result := range results { 92 row := getResultsRow(result, cols) 93 94 _, err := wc.Write([]byte(formatRow(row, cols, i, len(results)-1, tableName, format))) 95 if err != nil { 96 log.Fatal(err) 97 } 98 } 99 } 100 101 func getResultsRow(res result, cols []*SeedColumn) []string { 102 row := make([]string, len(cols)) 103 104 // set name 105 row[0] = res.name 106 // set format 107 row[1] = res.format 108 // set rows 109 row[2] = fmt.Sprintf("%d", res.rows) 110 // set cols 111 row[3] = fmt.Sprintf("%d", res.columns) 112 // set iterations 113 row[4] = fmt.Sprintf("%d", res.br.N) 114 // set time 115 row[5] = res.br.T.String() 116 // set bytes 117 row[6] = fmt.Sprintf("%v", res.br.Bytes) 118 // set mem_allocs 119 row[7] = fmt.Sprintf("%v", res.br.MemAllocs) 120 // set mem_bytes 121 row[8] = fmt.Sprintf("%v", res.br.MemBytes) 122 // set alloced_bytes_per_op 123 row[9] = fmt.Sprintf("%v", res.br.AllocedBytesPerOp()) 124 //set allocs_per_op 125 row[10] = fmt.Sprintf("%v", res.br.AllocsPerOp()) 126 // set datetime 127 t := time.Now() 128 row[11] = fmt.Sprintf("%04d-%02d-%02d %02d:%02d", t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute()) 129 return row 130 } 131 132 func genResultsCols() []*SeedColumn { 133 return []*SeedColumn{ 134 NewSeedColumn("name", false, types.StringKind, supplied), 135 NewSeedColumn("format", false, types.StringKind, supplied), 136 NewSeedColumn("rows", false, types.StringKind, supplied), 137 NewSeedColumn("columns", false, types.StringKind, supplied), 138 NewSeedColumn("iterations", false, types.StringKind, supplied), 139 NewSeedColumn("time", false, types.TimestampKind, supplied), 140 NewSeedColumn("bytes", false, types.IntKind, supplied), 141 NewSeedColumn("mem_allocs", false, types.IntKind, supplied), 142 NewSeedColumn("mem_bytes", false, types.IntKind, supplied), 143 NewSeedColumn("alloced_bytes_per_op", false, types.StringKind, supplied), 144 NewSeedColumn("allocs_per_op", false, types.StringKind, supplied), 145 NewSeedColumn("date_time", false, types.StringKind, supplied), 146 } 147 } 148 149 func serializeResults(results []result, path, tableName, format string) { 150 var sch *SeedSchema 151 switch format { 152 case csvExt: 153 sch = NewSeedSchema(len(results), genResultsCols(), csvExt) 154 default: 155 log.Fatalf("cannot serialize results, unsupported file format %s \n", format) 156 } 157 now := time.Now() 158 fs := filesys.LocalFS 159 resultsFile := filepath.Join(path, fmt.Sprintf("benchmark_results-%04d-%02d-%02d%s", now.Year(), now.Month(), now.Day(), format)) 160 wc, err := fs.OpenForWrite(resultsFile, os.ModePerm) 161 if err != nil { 162 log.Fatal(err) 163 } 164 defer wc.Close() 165 166 ds := NewRSImpl(wc, sch, results, tableName) 167 ds.GenerateData() 168 }