Skip to content

Instantly share code, notes, and snippets.

@cstrahan
Created April 24, 2017 22:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cstrahan/abc2620a4015319b95b9ce13f3d988ae to your computer and use it in GitHub Desktop.
Save cstrahan/abc2620a4015319b95b9ce13f3d988ae to your computer and use it in GitHub Desktop.
package main
import (
"bytes"
"fmt"
"io/ioutil"
"math"
)
const (
Color1 = "#F44336" // Red
Color2 = "#FF9800" // Orange
Color3 = "#FFEB3B" // Yellow
Color4 = "#00BCD4" // Cyan
Color5 = "#4CAF50" // Green
Color6 = "#009688" // Teal
Color7 = "#2196F3" // Blue
Color8 = "#9C27B0" // Purple
)
type Graph struct {
XLabel string
YLabel string
YLabelDY string
X0 float64
Y0 float64
X1 float64
Y1 float64
DX float64
DY float64
XMin float64
YMin float64
XMax float64
YMax float64
YLog bool
XMarks []Mark
YMarks []Mark
Lines []Line
Labels []Label
}
type Mark struct {
Pos float64
Text string
}
type Line struct {
Label string
LabelX float64
LabelY float64
Color string
Width float64
Data [][2]float64
}
type Label struct {
X float64
Y float64
XAlign string
YAlign string
Text string
}
func (g *Graph) ToX(v float64) float64 {
return g.X0 + (g.X1-g.X0)*((v-g.XMin)/(g.XMax-g.XMin))
}
func (g *Graph) ToY(v float64) float64 {
if g.YLog {
return g.Y0 + (g.Y1-g.Y0)*((math.Log(v)-math.Log(g.YMin))/(math.Log(g.YMax)-math.Log(g.YMin)))
}
return g.Y0 + (g.Y1-g.Y0)*((v-g.YMin)/(g.YMax-g.YMin))
}
func (g *Graph) SVG() []byte {
var buf bytes.Buffer
fmt.Fprintf(&buf, "<svg width=\"%dpt\" height=\"%dpt\" viewBox=\"0 0 %d %d\"\n xmlns=\"http://www.w3.org/2000/svg\">\n",
int(g.DX), int(g.DY), int(g.DX), int(g.DY))
fmt.Fprintf(&buf, "<defs>\n<clipPath id=\"grid\"><rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\"/></clipPath></defs>\n",
g.X0, g.Y1, g.X1-g.X0, g.Y0-g.Y1)
// Axis lines, marks, and mark labels.
fmt.Fprintf(&buf, "<path d=\"")
fmt.Fprintf(&buf, "M %.2f %.2f L %.2f %.2f ", g.X0, g.Y0, g.X0, g.Y1)
fmt.Fprintf(&buf, "M %.2f %.2f L %.2f %.2f ", g.X0, g.Y0, g.X1, g.Y0)
var text bytes.Buffer
for _, m := range g.XMarks {
x := g.ToX(m.Pos)
d := 5.0
if m.Text == "" {
d = 3
}
fmt.Fprintf(&buf, "M %.2f %.2f L %.2f %.2f ", x, g.Y0, x, g.Y0+d)
if m.Text != "" {
fmt.Fprintf(&text, "<text x=\"%.2f\" y=\"%.2f\" dy=\"1em\" text-anchor=\"middle\" font-size=\"10\">%s</text>\n", x, g.Y0+d, m.Text)
}
}
for _, m := range g.YMarks {
y := g.ToY(m.Pos)
d := 5.0
if m.Text == "" {
d = 3
}
fmt.Fprintf(&buf, "M %.2f %.2f L %.2f %.2f ", g.X0, y, g.X0-d, y)
if m.Text != "" {
fmt.Fprintf(&text, "<text x=\"%.2f\" y=\"%.2f\" dx=\"-0.3em\" dy=\"0.3em\" text-anchor=\"end\" font-size=\"10\">%s</text>\n", g.X0-d, y, m.Text)
}
}
fmt.Fprintf(&buf, "\" fill=\"transparent\" stroke=\"black\"/>\n")
buf.Write(text.Bytes())
// Axis labels.
if g.XLabel != "" {
fmt.Fprintf(&buf, "<text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\" font-size=\"11\" dy=\"2.5em\">%s</text>\n",
(g.X1+g.X0)/2, g.Y0, g.XLabel)
}
if g.YLabel != "" {
dy := "-2em"
if g.YLabelDY != "" {
dy = g.YLabelDY
}
fmt.Fprintf(&buf, "<g transform=\"translate(%.2f %.2f) rotate(-90)\"><text x=\"0\" y=\"0\" text-anchor=\"middle\" font-size=\"11\" dy=\"%s\">%s</text></g>\n",
g.X0, (g.Y1+g.Y0)/2, dy, g.YLabel)
}
// Lines
fmt.Fprintf(&buf, "<g clip-path=\"grid\">\n")
for _, line := range g.Lines {
fmt.Fprintf(&buf, "<path d=\"")
ch := "M"
for _, pt := range line.Data {
fmt.Fprintf(&buf, "%s %.2f %.2f", ch, g.ToX(pt[0]), g.ToY(pt[1]))
ch = " L"
}
fmt.Fprintf(&buf, "\" fill=\"transparent\" stroke=\"%s\" stroke-width=\"%.1f\"/>\n", line.Color, line.Width)
}
fmt.Fprintf(&buf, "</g>\n")
for _, line := range g.Lines {
if line.Label == "" {
continue
}
fmt.Fprintf(&buf, "<path d=\"")
x := line.LabelX
if x == 0 {
x = line.Data[len(line.Data)-1][0]
}
x = g.ToX(x)
y := line.LabelY
if y == 0 {
y = line.Data[len(line.Data)-1][1]
}
y = g.ToY(y)
fmt.Fprintf(&buf, " M %.2f %.2f L %.2f %.2f", x+Inch/4, y, x+Inch/2, y)
fmt.Fprintf(&buf, "\" fill=\"transparent\" stroke=\"%s\" stroke-width=\"%.1f\"/>\n", line.Color, line.Width)
fmt.Fprintf(&buf, "<text x=\"%.2f\" y=\"%.2f\" dy=\"0.3em\" font-size=\"9\">%s</text>\n", x+Inch/2+Inch/16, y, line.Label)
}
// Labels
for _, label := range g.Labels {
fmt.Fprintf(&buf, "<text x=\"%.2f\" y=\"%.2f\"", g.ToX(label.X), g.ToY(label.Y))
switch label.XAlign {
case "center":
fmt.Fprintf(&buf, " text-anchor=\"middle\"")
case "right":
fmt.Fprintf(&buf, " text-anchor=\"end\"")
}
switch label.YAlign {
case "center":
fmt.Fprintf(&buf, " dy=\"0.3em\"")
case "top":
fmt.Fprintf(&buf, " dy=\"1em\"")
}
fmt.Fprintf(&buf, " font-size=\"11\">%s</text>\n", label.Text)
}
fmt.Fprintf(&buf, "</svg>\n")
return buf.Bytes()
}
func (g *Graph) AutoXMarks() {
g.XMarks = autoMarks(g.XMin, g.XMax)
}
func (g *Graph) AutoYMarks() {
g.YMarks = autoMarks(g.YMin, g.YMax)
}
func autoMarks(min, max float64) []Mark {
scale := 1.0
for int(max/scale)-int(min/scale) > 10 {
scale *= 10
}
for int(max/scale)-int(min/scale) < 1 {
scale /= 10
}
var marks []Mark
for i := int(min / scale); float64(i)*scale <= max; i++ {
marks = append(marks, Mark{Text: fmt.Sprint(float64(i) * scale), Pos: float64(i) * scale})
if p := (float64(i) + 0.5) * scale; p <= max && scale > 1 {
marks = append(marks, Mark{Pos: p})
}
}
return marks
}
const Inch = 72.0
func main() {
g := &Graph{
XLabel: "pattern size <tspan style=\"font-style: italic\">n</tspan>",
X0: 0.5 * Inch,
X1: (0.5 + 2.5) * Inch,
Y0: (0.1 + 1.5) * Inch,
Y1: 0.1 * Inch,
DX: 3.25 * Inch,
DY: 2.1 * Inch,
XMin: 0,
YMin: 0,
YMax: 7.25,
Lines: []Line{
Line{},
},
Labels: []Label{
{
Y: 6,
XAlign: "right",
YAlign: "center",
},
},
}
g.YLabel = "time (minutes)"
g.Lines[0] = Line{
Color: "#c00",
Width: 2.0,
Data: [][2]float64{
{0, 4.8911e-05},
{1, 2.90413e-05},
{2, 3.68292e-05},
{3, 7.14572e-05},
{4, 0.000280084},
{5, 0.00265224},
{6, 0.0399743},
{7, 0.588281},
{8, 7.18658},
},
}
g.XMax = 8
g.Labels[0].X = 7
g.Labels[0].Text = "<tspan style=\"font-family: 'Inconsolata', monospace\">ls</tspan>"
g.AutoXMarks()
g.AutoYMarks()
ioutil.WriteFile("glob1.svg", g.SVG(), 0666)
g.YLabel = "time (ms)"
g.Lines[0] = Line{
Color: "#00f",
Width: 2.0,
Data: [][2]float64{
{0, 1.43909},
{1, 1.47637},
{2, 1.48331},
{3, 1.49517},
{4, 1.51284},
{5, 1.52364},
{6, 1.53863},
{7, 1.55547},
{8, 1.57037},
{9, 1.5826},
{10, 1.60071},
{11, 1.6203},
{12, 1.6312},
{13, 1.64203},
{14, 1.66992},
{15, 1.68861},
{16, 1.69519},
{17, 1.7203},
{18, 1.7295},
{19, 1.7554},
{20, 1.7758},
{21, 1.79486},
{22, 1.83495},
{23, 1.85332},
{24, 1.86697},
{25, 1.88521},
{26, 1.89894},
{27, 1.92536},
{28, 1.94536},
{29, 1.99545},
{30, 2.0099},
{31, 2.02431},
{32, 2.05334},
{33, 2.07537},
{34, 2.10333},
{35, 2.13579},
{36, 2.15802},
{37, 2.17934},
{38, 2.20948},
{39, 2.23249},
{40, 2.26358},
{41, 2.28074},
{42, 2.32731},
{43, 2.35436},
{44, 2.39507},
{45, 2.4247},
{46, 2.45651},
{47, 2.47193},
{48, 2.51619},
{49, 2.53839},
{50, 2.58134},
{51, 2.62019},
{52, 2.63301},
{53, 2.6786},
{54, 2.7337},
{55, 2.74277},
{56, 2.77387},
{57, 2.81395},
{58, 2.84587},
{59, 2.91166},
{60, 2.9355},
{61, 2.97022},
{62, 3.00078},
{63, 3.0401},
{64, 3.06739},
{65, 3.13164},
{66, 3.15914},
{67, 3.2148},
{68, 3.26457},
{69, 3.2891},
{70, 3.35357},
{71, 3.38114},
{72, 3.41628},
{73, 3.4704},
{74, 3.51955},
{75, 3.5626},
{76, 3.62813},
{77, 3.66333},
{78, 3.70191},
{79, 3.78555},
{80, 3.82436},
{81, 3.88056},
{82, 3.93706},
{83, 3.94907},
{84, 4.05134},
{85, 4.07482},
{86, 4.1267},
{87, 4.18599},
{88, 4.23299},
{89, 4.31395},
{90, 4.33191},
{91, 4.39525},
{92, 4.42133},
{93, 4.48976},
{94, 4.5401},
{95, 4.58719},
{96, 4.64591},
{97, 4.71859},
{98, 4.76698},
{99, 4.82806},
},
}
g.XMax = 100
g.Labels[0].X = 87.5
g.Labels[0].Text = "<tspan style=\"font-family: 'Inconsolata', monospace\">ls | grep</tspan>"
g.AutoXMarks()
g.AutoYMarks()
ioutil.WriteFile("glob2.svg", g.SVG(), 0666)
const LabelY1 = 4000.0
const LabelYScale = 2.0
g = &Graph{
XLabel: "pattern size <tspan style=\"font-style: italic\">n</tspan>",
YLabel: "time",
YLabelDY: "-4em",
X0: 0.75 * Inch,
X1: (0.75 + 5.25) * Inch,
Y0: (0.1 + 3.5) * Inch,
Y1: 0.1 * Inch,
DX: 7.5 * Inch,
DY: 4.1 * Inch,
XMin: 0,
XMax: 20,
YMin: 0.00010,
YMax: 25000.0,
YLog: true,
YMarks: []Mark{
{20000, ""},
{10000, "10000 s"},
{9000, ""}, {8000, ""}, {7000, ""}, {6000, ""}, {5000, ""}, {4000, ""}, {3000, ""}, {2000, ""},
{1000, "1000 s"},
{900, ""}, {800, ""}, {700, ""}, {600, ""}, {500, ""}, {400, ""}, {300, ""}, {200, ""},
{100, "100 s"},
{90, ""}, {80, ""}, {70, ""}, {60, ""}, {50, ""}, {40, ""}, {30, ""}, {20, ""},
{10, "10 s"},
{9, ""}, {8, ""}, {7, ""}, {6, ""}, {5, ""}, {4, ""}, {3, ""}, {2, ""},
{1, "1 s"},
{0.9, ""}, {0.8, ""}, {0.7, ""}, {0.6, ""}, {0.5, ""}, {0.4, ""}, {0.3, ""}, {0.2, ""},
{0.1, "100 ms"},
{0.09, ""}, {0.08, ""}, {0.07, ""}, {0.06, ""}, {0.05, ""}, {0.04, ""}, {0.03, ""}, {0.02, ""},
{0.01, "10 ms"},
{0.009, ""}, {0.008, ""}, {0.007, ""}, {0.006, ""}, {0.005, ""}, {0.004, ""}, {0.003, ""}, {0.002, ""},
{0.001, "1 ms"},
{0.0009, ""}, {0.0008, ""}, {0.0007, ""}, {0.0006, ""}, {0.0005, ""}, {0.0004, ""}, {0.0003, ""}, {0.0002, ""},
{0.0001, "100 us"},
},
XMarks: []Mark{
{0, "0"},
{1, ""},
{2, ""},
{3, ""},
{4, ""},
{5, "5"},
{6, ""},
{7, ""},
{8, ""},
{9, ""},
{10, "10"},
{11, ""},
{12, ""},
{13, ""},
{14, ""},
{15, "15"},
{16, ""},
{17, ""},
{18, ""},
{19, ""},
{20, "20"},
},
Lines: []Line{
Line{
Label: "tcsh 6.18.01",
Color: Color1,
Width: 1.5,
Data: [][2]float64{
{0, 0.004448880},
{1, 0.006431193},
{2, 0.005173464},
{3, 0.026750587},
{4, 0.500732081},
{5, 9.015299373},
{6, 142.768890376},
{7, 1952.555767944},
{8, 22940.221333328},
},
},
Line{
Label: "ksh 93u+20120801",
LabelY: LabelY1,
Color: Color2,
Width: 1.5,
Data: [][2]float64{
{0, 0.001050163},
{1, 0.000868984},
{2, 0.000975836},
{3, 0.002608253},
{4, 0.045094445},
{5, 0.803450403},
{6, 12.902227738},
{7, 177.752965717},
{8, 2211.436650459},
},
},
Line{
Label: "Plan 9 rc",
Color: Color3,
LabelY: LabelY1 / LabelYScale,
Width: 1.5,
Data: [][2]float64{
{0, 0.002205500},
{1, 0.003892799},
{2, 0.003442227},
{3, 0.008466353},
{4, 0.038269247},
{5, 0.516015808},
{6, 7.934463959},
{7, 110.193912116},
{8, 1314.421437116},
},
},
Line{
Label: "zsh 5.0.5",
Color: Color4,
Width: 1.5,
LabelY: LabelY1 / LabelYScale / LabelYScale,
Data: [][2]float64{
{0, 0.002088757},
{1, 0.003948585},
{2, 0.003979290},
{3, 0.005602784},
{4, 0.019969921},
{5, 0.323085859},
{6, 5.397274992},
{7, 78.776975755},
{8, 994.699093062},
},
},
Line{
Label: "rc 1.7.1",
Color: Color5,
Width: 1.5,
LabelY: LabelY1 / LabelYScale / LabelYScale / LabelYScale,
Data: [][2]float64{
{0, 0.001717890},
{1, 0.001503086},
{2, 0.001356468},
{3, 0.003084504},
{4, 0.019929715},
{5, 0.229489748},
{6, 3.693610576},
{7, 50.476608759},
{8, 601.638436616},
},
},
Line{
Label: "bash 4.3",
Color: Color6,
Width: 1.5,
LabelY: LabelY1 / LabelYScale / LabelYScale / LabelYScale / LabelYScale,
Data: [][2]float64{
{0, 0.001744280},
{1, 0.001830546},
{2, 0.002075035},
{3, 0.002840104},
{4, 0.011904460},
{5, 0.138909358},
{6, 2.362099111},
{7, 34.317349065},
{8, 434.075965074},
},
},
Line{
Label: "dash 0.5.7",
Color: Color7,
Width: 1.5,
LabelY: LabelY1 / LabelYScale / LabelYScale / LabelYScale / LabelYScale / LabelYScale,
Data: [][2]float64{
{0, 0.000763738},
{1, 0.000554199},
{2, 0.000545408},
{3, 0.000666228},
{4, 0.003953407},
{5, 0.069595180},
{6, 1.092959971},
{7, 15.170743911},
{8, 186.228944198},
},
},
Line{
Label: "csh 20110502",
Color: Color8,
Width: 1.5,
Data: [][2]float64{
{0, 0.021468033},
{1, 0.020593489},
{2, 0.020828153},
{3, 0.028540293},
{4, 0.020789366},
{5, 0.020464942},
{6, 0.020395209},
{7, 0.020762802},
{8, 0.020782494},
{9, 0.020609929},
{10, 0.020973340},
{11, 0.023544593},
{12, 0.032083391},
{13, 0.020648084},
{14, 0.028667412},
{15, 0.020449621},
{16, 0.020676539},
{17, 0.029357040},
{18, 0.020626247},
{19, 0.020780515},
{20, 0.030928707},
},
},
},
}
ioutil.WriteFile("glob3.svg", g.SVG(), 0666)
g.YMin = 0.00000030
g.YMax = 2000.0
g.YMarks = []Mark{
{2000, ""},
{1000, "1000 s"},
{900, ""}, {800, ""}, {700, ""}, {600, ""}, {500, ""}, {400, ""}, {300, ""}, {200, ""},
{100, "100 s"},
{90, ""}, {80, ""}, {70, ""}, {60, ""}, {50, ""}, {40, ""}, {30, ""}, {20, ""},
{10, "10 s"},
{9, ""}, {8, ""}, {7, ""}, {6, ""}, {5, ""}, {4, ""}, {3, ""}, {2, ""},
{1, "1 s"},
{0.9, ""}, {0.8, ""}, {0.7, ""}, {0.6, ""}, {0.5, ""}, {0.4, ""}, {0.3, ""}, {0.2, ""},
{0.1, "100 ms"},
{0.09, ""}, {0.08, ""}, {0.07, ""}, {0.06, ""}, {0.05, ""}, {0.04, ""}, {0.03, ""}, {0.02, ""},
{0.01, "10 ms"},
{0.009, ""}, {0.008, ""}, {0.007, ""}, {0.006, ""}, {0.005, ""}, {0.004, ""}, {0.003, ""}, {0.002, ""},
{0.001, "1 ms"},
{0.0009, ""}, {0.0008, ""}, {0.0007, ""}, {0.0006, ""}, {0.0005, ""}, {0.0004, ""}, {0.0003, ""}, {0.0002, ""},
{0.0001, "100 us"},
{0.00009, ""}, {0.00008, ""}, {0.00007, ""}, {0.00006, ""}, {0.00005, ""}, {0.00004, ""}, {0.00003, ""}, {0.00002, ""},
{0.00001, "10 us"},
{0.000009, ""}, {0.000008, ""}, {0.000007, ""}, {0.000006, ""}, {0.000005, ""}, {0.000004, ""}, {0.000003, ""}, {0.000002, ""},
{0.000001, "1 us"},
{0.0000009, ""}, {0.0000008, ""}, {0.0000007, ""}, {0.0000006, ""}, {0.0000005, ""}, {0.0000004, ""}, {0.0000003, ""},
}
const JavaY = 1824.9
const JavaScale = 2.2
const RustY = 0.00001464445 * 1.48
g.Lines = []Line{
Line{
Label: "Java 8",
Color: Color1,
Width: 1.5,
LabelY: JavaY,
Data: [][2]float64{
{0, 0.000065023},
{1, 0.000067364},
{2, 0.000354547},
{3, 0.001225556},
{4, 0.041045420},
{5, 0.522262194},
{6, 11.647746703},
{7, 108.762878663},
{8, 1824.943554702},
},
},
Line{
Label: "Perl 5.18.2",
Color: Color2,
Width: 1.5,
LabelY: JavaY / JavaScale,
Data: [][2]float64{
{0, 0.000001979},
{1, 0.000006342},
{2, 0.000030923},
{3, 0.000899100},
{4, 0.021647429},
{5, 0.419456720},
{6, 6.774190903},
{7, 92.677416563},
{8, 1098.529198885},
},
},
Line{
Label: "BSD libc",
Color: Color3,
Width: 1.5,
LabelY: JavaY / JavaScale / JavaScale,
Data: [][2]float64{
{0, 0.000001179},
{1, 0.000012861},
{2, 0.000063309},
{3, 0.001470879},
{4, 0.024432457},
{5, 0.414762696},
{6, 6.181407079},
{7, 84.698674273},
{8, 999.673042145},
},
},
Line{
Label: "Python 3.4.3",
Color: "#777",
Width: 1.5,
LabelY: JavaY / JavaScale / JavaScale / JavaScale,
Data: [][2]float64{
{0, 0.000012600},
{1, 0.000059500},
{2, 0.000069500},
{3, 0.000541600},
{4, 0.010053500},
{5, 0.140167000},
{6, 1.968111000},
{7, 27.896194000},
{8, 350.594924000},
},
},
Line{
Label: "Tcl 8.6.1",
Color: Color4,
Width: 1.5,
LabelY: JavaY / JavaScale / JavaScale / JavaScale / JavaScale,
Data: [][2]float64{
{0, 0.000010},
{1, 0.000014},
{2, 0.000018},
{3, 0.000192},
{4, 0.004870},
{5, 0.103335},
{6, 1.749018},
{7, 24.910158},
{8, 314.548899},
},
},
Line{
Label: "Rust 1.16.0",
Color: Color5,
Width: 1.5,
LabelY: RustY,
Data: [][2]float64{
{0, 0.00000366154},
{1, 0.0000137192},
{2, 0.000014104619999999998},
{3, 0.00001453812},
{4, 0.00001362235},
{5, 0.00001377523},
{6, 0.00001383179},
{7, 0.000013869380000000002},
{8, 0.00001422967},
{9, 0.000014255940000000001},
{10, 0.00001406678},
{11, 0.00001431524},
{12, 0.00001376724},
{13, 0.000013525849999999999},
{14, 0.000014945740000000001},
{15, 0.00001364573},
{16, 0.00001391383},
{17, 0.000014074370000000002},
{18, 0.0000141275},
{19, 0.000014247540000000001},
{20, 0.00001464445},
},
},
Line{
Label: "Go 1.8",
Color: Color6,
Width: 1.5,
LabelY: RustY / JavaScale,
Data: [][2]float64{
{0, 0.000001152},
{1, 0.000007951},
{2, 0.000006988},
{3, 0.000008592},
{4, 0.000006027},
{5, 0.000007345},
{6, 0.000005920},
{7, 0.000006541},
{8, 0.000008204},
{9, 0.000006657},
{10, 0.000006520},
{11, 0.000006505},
{12, 0.000007225},
{13, 0.000007631},
{14, 0.000006963},
{15, 0.000008565},
{16, 0.000008175},
{17, 0.000007436},
{18, 0.000007050},
{19, 0.000006558},
{20, 0.000007871},
},
},
Line{
Label: "Ruby 1.9.3",
Color: Color7,
Width: 1.5,
LabelY: RustY / JavaScale / JavaScale,
Data: [][2]float64{
{0, 0.000001141},
{1, 0.000004713},
{2, 0.000004712},
{3, 0.000004711},
{4, 0.000004733},
{5, 0.000004766},
{6, 0.000004822},
{7, 0.000004841},
{8, 0.000004884},
{9, 0.000004925},
{10, 0.000004904},
{11, 0.000004947},
{12, 0.000005063},
{13, 0.000005085},
{14, 0.000005073},
{15, 0.000005075},
{16, 0.000005115},
{17, 0.000005131},
{18, 0.000005125},
{19, 0.000005164},
{20, 0.000005325},
},
},
Line{
Label: "glibc 2.19",
Color: Color8,
Width: 1.5,
LabelY: RustY / JavaScale / JavaScale / JavaScale,
Data: [][2]float64{
{0, 0.000000354},
{1, 0.000002516},
{2, 0.000002521},
{3, 0.000002564},
{4, 0.000002574},
{5, 0.000002606},
{6, 0.000002627},
{7, 0.000002655},
{8, 0.000002679},
{9, 0.000002688},
{10, 0.000002693},
{11, 0.000002746},
{12, 0.000002733},
{13, 0.000002753},
{14, 0.000002797},
{15, 0.000002812},
{16, 0.000002815},
{17, 0.000002831},
{18, 0.000002874},
{19, 0.000002954},
{20, 0.000002885},
},
},
}
ioutil.WriteFile("glob4.svg", g.SVG(), 0666)
g.YMin = 0.000010
g.YMax = 1000.0
g.YMarks = []Mark{
{1000, "1000 s"},
{900, ""}, {800, ""}, {700, ""}, {600, ""}, {500, ""}, {400, ""}, {300, ""}, {200, ""},
{100, "100 s"},
{90, ""}, {80, ""}, {70, ""}, {60, ""}, {50, ""}, {40, ""}, {30, ""}, {20, ""},
{10, "10 s"},
{9, ""}, {8, ""}, {7, ""}, {6, ""}, {5, ""}, {4, ""}, {3, ""}, {2, ""},
{1, "1 s"},
{0.9, ""}, {0.8, ""}, {0.7, ""}, {0.6, ""}, {0.5, ""}, {0.4, ""}, {0.3, ""}, {0.2, ""},
{0.1, "100 ms"},
{0.09, ""}, {0.08, ""}, {0.07, ""}, {0.06, ""}, {0.05, ""}, {0.04, ""}, {0.03, ""}, {0.02, ""},
{0.01, "10 ms"},
{0.009, ""}, {0.008, ""}, {0.007, ""}, {0.006, ""}, {0.005, ""}, {0.004, ""}, {0.003, ""}, {0.002, ""},
{0.001, "1 ms"},
{0.0009, ""}, {0.0008, ""}, {0.0007, ""}, {0.0006, ""}, {0.0005, ""}, {0.0004, ""}, {0.0003, ""}, {0.0002, ""},
{0.0001, "100 us"},
{0.00009, ""}, {0.00008, ""}, {0.00007, ""}, {0.00006, ""}, {0.00005, ""}, {0.00004, ""}, {0.00003, ""}, {0.00002, ""},
{0.00001, "10 us"},
}
const FTPScale = 2.2
g.Lines = []Line{
Line{
Label: "tnftpd (macOS 10.12.4)",
Color: Color1,
Width: 1.5,
Data: [][2]float64{
{0, 0.000726218},
{1, 0.000701438},
{2, 0.000681952},
{3, 0.001169221},
{4, 0.016168262},
{5, 0.279887617},
{6, 5.131108941},
{7, 73.196001685},
{8, 908.508298457},
},
},
Line{
Label: "Pure-FTPd 1.0.36",
Color: Color2,
Width: 1.5,
LabelX: 8,
Data: [][2]float64{
{0, 0.000078834},
{1, 0.000087225},
{2, 0.000114032},
{3, 0.001177995},
{4, 0.025545281},
{5, 0.474122740},
{6, 7.175956716},
{7, 17.000464818},
},
},
Line{
Label: "netkit ftpd 0.17",
Color: Color3,
Width: 1.5,
Data: [][2]float64{
{0, 0.039975602},
{1, 0.039978648},
{2, 0.039984980},
{3, 0.040032031},
{4, 0.043969668},
{5, 0.039918785},
{6, 0.040091206},
{7, 0.039898988},
{8, 0.039990887},
{9, 0.040013264},
{10, 0.039972922},
{11, 0.039985223},
{12, 0.039983797},
{13, 0.039964445},
{14, 0.039978644},
{15, 0.039982385},
{16, 0.039990214},
{17, 0.039979283},
{18, 0.039933946},
{19, 0.040045011},
{20, 0.039942230},
},
},
Line{
Label: "Plan 9 ip/ftpd",
Color: Color4,
Width: 1.5,
Data: [][2]float64{
{0, 0.001658756},
{1, 0.001520307},
{2, 0.001400825},
{3, 0.001281890},
{4, 0.001480524},
{5, 0.001331127},
{6, 0.001288928},
{7, 0.001295951},
{8, 0.001275298},
{9, 0.001318116},
{10, 0.001283259},
{11, 0.001276441},
{12, 0.001327904},
{13, 0.001307317},
{14, 0.001277501},
{15, 0.001292110},
{16, 0.001321254},
{17, 0.001333817},
{18, 0.001294728},
{19, 0.001297300},
{20, 0.001286038},
},
},
Line{
Label: "ProFTPD 1.3.5",
Color: Color5,
Width: 1.5,
Data: [][2]float64{
{0, 0.000183692},
{1, 0.000283286},
{2, 0.000277546},
{3, 0.000276985},
{4, 0.000272333},
{5, 0.000267839},
{6, 0.000273773},
{7, 0.000269477},
{8, 0.000266262},
{9, 0.000262938},
{10, 0.000262621},
{11, 0.000272360},
{12, 0.000271251},
{13, 0.000308269},
{14, 0.000271010},
{15, 0.000265288},
{16, 0.000264589},
{17, 0.000275604},
{18, 0.000418055},
{19, 0.000353263},
{20, 0.000341168},
},
},
Line{
Label: "vsftpd 3.0.2",
Color: Color6,
Width: 1.5,
Data: [][2]float64{
{0, 0.000067488},
{1, 0.000061585},
{2, 0.000058776},
{3, 0.000063039},
{4, 0.000053424},
{5, 0.000059835},
{6, 0.000059034},
{7, 0.000055986},
{8, 0.000059693},
{9, 0.000057138},
{10, 0.000056172},
{11, 0.000057901},
{12, 0.000057048},
{13, 0.000057297},
{14, 0.000056441},
{15, 0.000056472},
{16, 0.000055606},
{17, 0.000057615},
{18, 0.000056544},
{19, 0.000056045},
{20, 0.000057401},
},
},
}
ioutil.WriteFile("glob5.svg", g.SVG(), 0666)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment