mirror of
https://gitlab.com/cznic/sqlite.git
synced 2025-07-17 00:24:45 +00:00
237 lines
6.0 KiB
Go
237 lines
6.0 KiB
Go
// Copyright 2021 The Sqlite Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// helpers for plotting benchmark results
|
|
package benchmark
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path"
|
|
|
|
"github.com/wcharczuk/go-chart"
|
|
"github.com/wcharczuk/go-chart/drawing"
|
|
)
|
|
|
|
const (
|
|
yAxisCeilStep = 200000
|
|
)
|
|
|
|
var transparentColor = drawing.ColorWhite.WithAlpha(0)
|
|
|
|
type GraphCompareOfNRows struct {
|
|
// this fields should be set externally
|
|
rowCountsE []int
|
|
title string
|
|
palette chart.ColorPalette
|
|
|
|
// this fields are for private use
|
|
seriesNameS []string
|
|
seriesValuesS [][]float64
|
|
}
|
|
|
|
func (g *GraphCompareOfNRows) AddSeries(name string, values []float64) {
|
|
g.seriesNameS = append(g.seriesNameS, name)
|
|
g.seriesValuesS = append(g.seriesValuesS, values)
|
|
}
|
|
|
|
func (g *GraphCompareOfNRows) Render(filename string) error {
|
|
// new chart object
|
|
graph := g.newGraph()
|
|
|
|
// generate series objects for graph
|
|
for i, seriesName := range g.seriesNameS {
|
|
// get corresponding series values
|
|
seriesValues := g.seriesValuesS[i]
|
|
|
|
// create series object
|
|
graph.Series = append(graph.Series, g.createSeries(seriesName, seriesValues))
|
|
|
|
// adjust max for Y axis
|
|
yMax := (int(max(seriesValues...)/yAxisCeilStep) + 1) * yAxisCeilStep // a special case of ceil()
|
|
if graph.YAxis.Range.GetMax() < float64(yMax) {
|
|
graph.YAxis.Range = &chart.ContinuousRange{
|
|
Min: 0,
|
|
Max: float64(yMax),
|
|
}
|
|
}
|
|
|
|
// skip annotations for first series
|
|
if i == 0 {
|
|
continue
|
|
}
|
|
|
|
// for every series except first, we create a ratio annotation s[X]/s[0]
|
|
annotations := &chart.AnnotationSeries{}
|
|
for i, v := range seriesValues {
|
|
annotations.Annotations = append(annotations.Annotations, g.newRatioAnnotation(
|
|
float64(g.rowCountsE[i]),
|
|
v,
|
|
v/g.seriesValuesS[0][i],
|
|
))
|
|
|
|
}
|
|
|
|
// append annotations to graph
|
|
graph.Series = append(graph.Series, annotations)
|
|
}
|
|
|
|
// add legend
|
|
graph.Elements = []chart.Renderable{
|
|
chart.Legend(graph, chart.Style{
|
|
FontSize: 12,
|
|
StrokeColor: transparentColor,
|
|
FillColor: g.palette.CanvasColor(),
|
|
FontColor: g.palette.TextColor().WithAlpha(192),
|
|
}),
|
|
}
|
|
|
|
// write into file
|
|
if err := os.MkdirAll(path.Dir(filename), 0775); err != nil {
|
|
return err
|
|
}
|
|
f, err := os.Create(filename)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer f.Close()
|
|
if err := graph.Render(chart.PNG, f); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (g *GraphCompareOfNRows) createSeries(name string, values []float64) chart.Series {
|
|
// convert E values of rowCount onto float64
|
|
var xValues []float64
|
|
for _, e := range g.rowCountsE {
|
|
xValues = append(xValues, float64(e))
|
|
}
|
|
|
|
// create series
|
|
series := &chart.ContinuousSeries{
|
|
Name: name,
|
|
Style: chart.Style{
|
|
DotWidth: 2.5,
|
|
Show: true,
|
|
StrokeWidth: 1.5,
|
|
},
|
|
XValues: xValues,
|
|
YValues: values,
|
|
}
|
|
|
|
// save in series slice
|
|
return series
|
|
}
|
|
|
|
func (g *GraphCompareOfNRows) newGraph() *chart.Chart {
|
|
return &chart.Chart{
|
|
ColorPalette: g.palette,
|
|
Title: g.title,
|
|
TitleStyle: chart.Style{
|
|
Show: true,
|
|
},
|
|
Background: chart.Style{
|
|
Padding: chart.Box{
|
|
Top: 20,
|
|
Left: 20,
|
|
},
|
|
},
|
|
Canvas: chart.Style{},
|
|
XAxis: chart.XAxis{
|
|
Style: chart.StyleShow(),
|
|
NameStyle: chart.StyleShow(),
|
|
Name: "rows",
|
|
Ticks: g.genXticks(),
|
|
},
|
|
YAxis: chart.YAxis{
|
|
Range: &chart.ContinuousRange{},
|
|
Style: chart.StyleShow(),
|
|
Name: "rows/sec",
|
|
NameStyle: chart.StyleShow(),
|
|
ValueFormatter: func(v interface{}) string { return fmt.Sprintf("%.0f", v) },
|
|
},
|
|
}
|
|
}
|
|
|
|
func (g *GraphCompareOfNRows) newRatioAnnotation(x, y, ratio float64) chart.Value2 {
|
|
return chart.Value2{
|
|
XValue: x,
|
|
YValue: y,
|
|
Label: fmt.Sprintf("%.2fx", ratio),
|
|
Style: chart.Style{
|
|
FontSize: 8,
|
|
TextHorizontalAlign: chart.TextHorizontalAlignLeft,
|
|
FillColor: transparentColor, // full tranparency
|
|
StrokeColor: transparentColor, // full transparency
|
|
FontColor: g.palette.TextColor().WithAlpha(255), // no transaprency
|
|
TextRotationDegrees: 45,
|
|
},
|
|
}
|
|
}
|
|
|
|
func (g *GraphCompareOfNRows) genXticks() []chart.Tick {
|
|
var ticks []chart.Tick
|
|
for i, e := range g.rowCountsE {
|
|
ticks = append(ticks, chart.Tick{
|
|
Value: float64(e),
|
|
Label: fmt.Sprintf("1e%d", i+1),
|
|
})
|
|
}
|
|
return ticks
|
|
}
|
|
|
|
func max(f ...float64) float64 {
|
|
if len(f) == 0 {
|
|
return 0
|
|
}
|
|
m := f[0]
|
|
for i := 1; i < len(f); i++ {
|
|
if m < f[i] {
|
|
m = f[i]
|
|
}
|
|
}
|
|
return m
|
|
}
|
|
|
|
type palette struct {
|
|
bgColor drawing.Color
|
|
bgStrokeColor drawing.Color
|
|
canvasColor drawing.Color
|
|
canvasStrokeColor drawing.Color
|
|
axisStrokeColor drawing.Color
|
|
textColor drawing.Color
|
|
seriesColor []drawing.Color
|
|
}
|
|
|
|
func (p *palette) BackgroundColor() drawing.Color { return p.bgColor }
|
|
func (p *palette) BackgroundStrokeColor() drawing.Color { return p.bgStrokeColor }
|
|
func (p *palette) CanvasColor() drawing.Color { return p.canvasColor }
|
|
func (p *palette) CanvasStrokeColor() drawing.Color { return p.canvasStrokeColor }
|
|
func (p *palette) AxisStrokeColor() drawing.Color { return p.axisStrokeColor }
|
|
func (p *palette) TextColor() drawing.Color { return p.textColor }
|
|
func (p *palette) GetSeriesColor(i int) drawing.Color { return p.seriesColor[i%len(p.seriesColor)] }
|
|
|
|
var DarkPalette = &palette{
|
|
bgColor: drawing.ColorFromHex("252526"),
|
|
canvasColor: drawing.ColorFromHex("1e1e1e1"),
|
|
textColor: drawing.ColorFromHex("d4d4d4").WithAlpha(128),
|
|
axisStrokeColor: drawing.ColorFromHex("d4d4d4").WithAlpha(128),
|
|
seriesColor: []drawing.Color{
|
|
drawing.ColorFromHex("d5d5a5"),
|
|
drawing.ColorFromHex("569cd5"),
|
|
},
|
|
}
|
|
|
|
var LightPalette = &palette{
|
|
canvasColor: drawing.ColorFromHex("f2f2f2"),
|
|
bgColor: drawing.ColorFromHex("f5f5f5"),
|
|
textColor: drawing.ColorFromHex("393939").WithAlpha(128),
|
|
axisStrokeColor: drawing.ColorFromHex("393939").WithAlpha(128),
|
|
seriesColor: []drawing.Color{
|
|
drawing.ColorFromHex("aa3731"),
|
|
drawing.ColorFromHex("5a77c7"),
|
|
},
|
|
}
|