|
| 1 | +package main |
| 2 | + |
| 3 | +import ( |
| 4 | + "bufio" |
| 5 | + "fmt" |
| 6 | + "os" |
| 7 | + "strconv" |
| 8 | + "strings" |
| 9 | + |
| 10 | + "github.com/go-echarts/go-echarts/v2/charts" |
| 11 | + "github.com/go-echarts/go-echarts/v2/opts" |
| 12 | +) |
| 13 | + |
| 14 | +func parseBenchmarks() []BenchData { |
| 15 | + f, err := os.OpenFile("bench.log", os.O_RDONLY, os.ModePerm) |
| 16 | + if err != nil { |
| 17 | + panic(err) |
| 18 | + } |
| 19 | + defer f.Close() |
| 20 | + |
| 21 | + entries := []BenchData{} |
| 22 | + sc := bufio.NewScanner(f) |
| 23 | + for sc.Scan() { |
| 24 | + line := sc.Text() |
| 25 | + if !strings.HasPrefix(line, "Benchmark") { |
| 26 | + continue |
| 27 | + } |
| 28 | + |
| 29 | + fields := strings.Fields(line) |
| 30 | + |
| 31 | + // name |
| 32 | + suite := strings.Replace(strings.Split(fields[0], "/")[0], "Benchmark", "", -1) |
| 33 | + sub := strings.Split(fields[0], "/")[1] |
| 34 | + name := sub |
| 35 | + param := "1" |
| 36 | + if strings.Contains(sub, "_") { |
| 37 | + name = strings.Split(strings.Split(fields[0], "/")[1], "_")[0] |
| 38 | + param = strings.Split(strings.Split(fields[0], "/")[1], "_")[1] |
| 39 | + |
| 40 | + if strings.Contains(param, "-") { |
| 41 | + param = strings.Split(param, "-")[0] |
| 42 | + } |
| 43 | + } |
| 44 | + |
| 45 | + // math |
| 46 | + paramValue, _ := strconv.Atoi(param) |
| 47 | + iteration, _ := strconv.Atoi(fields[1]) |
| 48 | + speed, _ := strconv.Atoi(fields[2]) |
| 49 | + data, _ := strconv.Atoi(fields[4]) |
| 50 | + alloc, _ := strconv.Atoi(fields[6]) |
| 51 | + |
| 52 | + entries = append(entries, BenchData{ |
| 53 | + Suite: suite, |
| 54 | + Name: name, |
| 55 | + Param: paramValue, |
| 56 | + Iter: iteration, |
| 57 | + Speed: speed, |
| 58 | + Data: data, |
| 59 | + Alloc: alloc, |
| 60 | + }) |
| 61 | + } |
| 62 | + return entries |
| 63 | +} |
| 64 | + |
| 65 | +type BenchData struct { |
| 66 | + Suite string |
| 67 | + Name string |
| 68 | + Param int |
| 69 | + Iter int |
| 70 | + Speed int |
| 71 | + Data int |
| 72 | + Alloc int |
| 73 | +} |
| 74 | + |
| 75 | +func groupBySuite(data []BenchData) map[string][]BenchData { |
| 76 | + entries := map[string][]BenchData{} |
| 77 | + for _, bench := range data { |
| 78 | + entries[bench.Suite] = append(entries[bench.Suite], bench) |
| 79 | + } |
| 80 | + return entries |
| 81 | +} |
| 82 | + |
| 83 | +func generateLineSpeedData(data []BenchData, filters ...string) []opts.LineData { |
| 84 | + items := make([]opts.LineData, 0) |
| 85 | + for _, v := range data { |
| 86 | + for _, f := range filters { |
| 87 | + if !strings.Contains(v.Name, f) { |
| 88 | + continue |
| 89 | + } |
| 90 | + } |
| 91 | + items = append(items, opts.LineData{Value: 1000000000 / v.Speed}) |
| 92 | + } |
| 93 | + return items |
| 94 | +} |
| 95 | + |
| 96 | +func generateLineAllocData(data []BenchData, filters ...string) []opts.LineData { |
| 97 | + items := make([]opts.LineData, 0) |
| 98 | + for _, v := range data { |
| 99 | + for _, f := range filters { |
| 100 | + if !strings.Contains(v.Name, f) { |
| 101 | + continue |
| 102 | + } |
| 103 | + } |
| 104 | + items = append(items, opts.LineData{Value: v.Alloc}) |
| 105 | + } |
| 106 | + return items |
| 107 | +} |
| 108 | + |
| 109 | +func generateInsertManyCPULines(data []BenchData, name string, filter string) *charts.Line { |
| 110 | + entries := groupBySuite(data) |
| 111 | + |
| 112 | + line := charts.NewLine() |
| 113 | + line.SetGlobalOptions( |
| 114 | + charts.WithTitleOpts(opts.Title{ |
| 115 | + Title: name + "|CPU", |
| 116 | + Subtitle: "Higher is Better (op/s)", |
| 117 | + }), |
| 118 | + charts.WithInitializationOpts(opts.Initialization{ |
| 119 | + Theme: "shine", |
| 120 | + Width: "576px", |
| 121 | + Height: "320px", |
| 122 | + }), |
| 123 | + ) |
| 124 | + line.SetXAxis([]string{"10", "25", "50", "100", "250", "500"}) |
| 125 | + |
| 126 | + for k, v := range entries { |
| 127 | + if !strings.Contains(k, filter) { |
| 128 | + continue |
| 129 | + } |
| 130 | + |
| 131 | + line.AddSeries(strings.ReplaceAll(k, filter, ""), generateLineSpeedData(v, name)) |
| 132 | + } |
| 133 | + |
| 134 | + return line |
| 135 | +} |
| 136 | + |
| 137 | +func generateInsertManyAllocLines(data []BenchData, name string, filter string) *charts.Line { |
| 138 | + entries := groupBySuite(data) |
| 139 | + |
| 140 | + line := charts.NewLine() |
| 141 | + line.SetGlobalOptions( |
| 142 | + charts.WithTitleOpts(opts.Title{ |
| 143 | + Title: name + "|Mem", |
| 144 | + Subtitle: "Lower is Better (allocs/op)", |
| 145 | + }), |
| 146 | + charts.WithInitializationOpts(opts.Initialization{ |
| 147 | + Theme: "shine", |
| 148 | + Width: "576px", |
| 149 | + Height: "320px", |
| 150 | + }), |
| 151 | + ) |
| 152 | + line.SetXAxis([]string{"10", "25", "50", "100", "250", "500"}) |
| 153 | + |
| 154 | + for k, v := range entries { |
| 155 | + if !strings.Contains(k, filter) { |
| 156 | + continue |
| 157 | + } |
| 158 | + line.AddSeries(strings.ReplaceAll(k, filter, ""), generateLineAllocData(v, name)) |
| 159 | + } |
| 160 | + |
| 161 | + return line |
| 162 | +} |
| 163 | + |
| 164 | +func main() { |
| 165 | + data := parseBenchmarks() |
| 166 | + |
| 167 | + for _, db := range []string{"Postgres", "SQLite"} { |
| 168 | + for _, op := range []string{"InsertMany", "FindMany"} { |
| 169 | + f1, _ := os.Create(fmt.Sprintf("docs/public/bench_%s_%s_cpu.html", strings.ToLower(db), strings.ToLower(op))) |
| 170 | + defer f1.Close() |
| 171 | + generateInsertManyCPULines(data, op, db).Render(f1) |
| 172 | + |
| 173 | + f2, _ := os.Create(fmt.Sprintf("docs/public/bench_%s_%s_alloc.html", strings.ToLower(db), strings.ToLower(op))) |
| 174 | + defer f2.Close() |
| 175 | + generateInsertManyAllocLines(data, op, db).Render(f2) |
| 176 | + } |
| 177 | + } |
| 178 | +} |
0 commit comments