Advertisement
Guest User

Untitled

a guest
Feb 22nd, 2019
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.69 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4. "encoding/csv"
  5. "image/color"
  6. "os"
  7. "sort"
  8. "strconv"
  9.  
  10. "gonum.org/v1/plot"
  11. "gonum.org/v1/plot/plotter"
  12. "gonum.org/v1/plot/vg"
  13. "gonum.org/v1/plot/vg/draw"
  14. "gonum.org/v1/plot/vg/vgimg"
  15. "gorgonia.org/tensor"
  16. "gorgonia.org/tensor/native"
  17. )
  18.  
  19. func main() {
  20. sizeCPU := func(a Bench) (float64, float64) { return a.Size, a.CPU }
  21. // median := func(a []float64) float64 { return ntile(a, 0.5) }
  22. all := parse(ingest("data.csv"))
  23. list := []string{
  24. "gcc", "ocaml", "node",
  25. "java", "go", "ghc",
  26. "rust", "julia", "swift",
  27. }
  28.  
  29. ps := make([]*plot.Plot, 0, len(list))
  30. for _, l := range list {
  31. lang := filter(all, func(a Bench) bool { return a.Language == l })
  32. lang = argminByName(lang, func(a Bench) float64 { return a.CPU })
  33. p := plotAll(all, sizeCPU)
  34. p.BackgroundColor = color.RGBA{R: 255}
  35. p.X.Max = 2000
  36. p.Y.Max = 150
  37. p.Title.Text = l
  38.  
  39. plotStar(p, lang, sizeCPU, mean)
  40. ps = append(ps, p)
  41. }
  42. // Draw plots in a tiled fashion
  43. cols := 3
  44. t := tensor.New(tensor.WithBacking(ps), tensor.WithShape(len(list)/cols, cols))
  45. matUgh, err := native.Matrix(t)
  46. dieIfErr(err)
  47. mat := matUgh.([][]*plot.Plot)
  48. tiles := draw.Tiles{Rows: t.Shape()[0], Cols: t.Shape()[1]}
  49. img := vgimg.New(60*vg.Centimeter, 60*vg.Centimeter)
  50. canvas := draw.New(img)
  51. mini := plot.Align(mat, tiles, canvas)
  52. for i := 0; i < tiles.Rows; i++ {
  53. for j := 0; j < tiles.Cols; j++ {
  54. mat[i][j].Draw(mini[i][j])
  55. }
  56. }
  57. w, err := os.Create("gb.png")
  58. dieIfErr(err)
  59. png := vgimg.PngCanvas{Canvas: img}
  60. png.WriteTo(w)
  61. }
  62.  
  63. func ingest(filename string) [][]string {
  64. f, err := os.Open(filename)
  65. dieIfErr(err)
  66. r := csv.NewReader(f)
  67. records, err := r.ReadAll()
  68. dieIfErr(err)
  69. return records
  70. }
  71.  
  72. type Bench struct {
  73. Name string
  74. Language string
  75. Size float64
  76. CPU, Mem float64
  77. }
  78.  
  79. func parse(recs [][]string) []Bench {
  80. retVal := make([]Bench, 0, len(recs))
  81. for i, r := range recs {
  82. if i == 0 {
  83. continue
  84. }
  85. size, err := strconv.ParseFloat(r[4], 64)
  86. dieIfErr(err)
  87. cpu, err := strconv.ParseFloat(r[5], 64)
  88. dieIfErr(err)
  89. mem, err := strconv.ParseFloat(r[6], 64)
  90. dieIfErr(err)
  91.  
  92. b := Bench{
  93. Name: r[0],
  94. Language: r[1],
  95. Size: size,
  96. CPU: cpu,
  97. Mem: mem,
  98. }
  99. retVal = append(retVal, b)
  100. }
  101. return retVal
  102. }
  103.  
  104. // filter filters a list of Bench according to the criteria given in f
  105. func filter(a []Bench, f func(a Bench) bool) (retVal []Bench) {
  106. for i := range a {
  107. if f(a[i]) {
  108. retVal = append(retVal, a[i])
  109. }
  110. }
  111. return retVal
  112. }
  113.  
  114. // reduce2 reduces a pair of numbers given by f, using the reduction function g
  115. func reduce2(a []Bench, f func(a Bench) (float64, float64), g func([]float64) float64) (float64, float64) {
  116. xs, ys := make([]float64, 0, len(a)), make([]float64, 0, len(a))
  117. for i := range a {
  118. x, y := f(a[i])
  119. xs = append(xs, x)
  120. ys = append(ys, y)
  121. }
  122. return g(xs), g(ys)
  123. }
  124.  
  125. func argminByName(a []Bench, f func(a Bench) float64) (retVal []Bench) {
  126. m := make(map[string]Bench)
  127. for _, b := range a {
  128. if v, ok := m[b.Name]; ok {
  129. if f(b) < f(v) {
  130. m[b.Name] = b
  131. }
  132. continue
  133. }
  134. m[b.Name] = b
  135. }
  136. for _, v := range m {
  137. retVal = append(retVal, v)
  138. }
  139. return retVal
  140. }
  141.  
  142. // makeXYs extracts pairs of desired numbers given by f
  143. func makeXYs(a []Bench, f func(a Bench) (float64, float64)) plotter.XYs {
  144. retVal := make(plotter.XYs, len(a))
  145. for i := range a {
  146. x, y := f(a[i])
  147. retVal[i].X = x
  148. retVal[i].Y = y
  149. }
  150. return retVal
  151. }
  152.  
  153. // plotAll plots all the points of the given []Bench
  154. func plotAll(a []Bench, f func(a Bench) (float64, float64)) *plot.Plot {
  155. p, err := plot.New()
  156. dieIfErr(err)
  157. s, err := plotter.NewScatter(makeXYs(a, f))
  158. dieIfErr(err)
  159. p.Add(s)
  160. return p
  161. }
  162.  
  163. // plotstar adds a line star thing into the plot
  164. func plotStar(p *plot.Plot, a []Bench, f func(a Bench) (float64, float64), g func([]float64) float64) {
  165. s := new(star)
  166. s.XYs = makeXYs(a, f)
  167. s.mx, s.my = reduce2(a, f, g)
  168. s.trx, s.try = p.X.Max, p.Y.Max
  169. s.LineStyle = plotter.DefaultLineStyle
  170. s.LineStyle.Color = color.RGBA{R: 255, A: 255}
  171. p.Add(s)
  172. }
  173.  
  174. // star is a data structure used for plotting line stars
  175. type star struct {
  176. plotter.XYs
  177. draw.LineStyle
  178. mx, my float64
  179. trx, try float64 // truncate at
  180. }
  181.  
  182. func (s *star) Plot(c draw.Canvas, p *plot.Plot) {
  183. tx, ty := p.Transforms(&c)
  184. trx, try := tx(s.trx), ty(s.try)
  185. ls := s.LineStyle
  186. mx, my := tx(s.mx), ty(s.my)
  187. for _, xy := range s.XYs {
  188. x := tx(xy.X)
  189. y := ty(xy.Y)
  190. if x > trx {
  191. x = trx
  192. }
  193. if y > try {
  194. y = try
  195. }
  196. c.StrokeLine2(ls, mx, my, x, y)
  197. }
  198. }
  199.  
  200. func dieIfErr(err error) {
  201. if err != nil {
  202. panic(err)
  203. }
  204. }
  205.  
  206. func mean(a []float64) float64 {
  207. var s float64
  208. for _, v := range a {
  209. s += v
  210. }
  211. return s / float64(len(a))
  212. }
  213.  
  214. func ntile(a []float64, p float64) float64 {
  215. sort.Float64s(a)
  216. at := int(float64(len(a)) * p)
  217. return a[at]
  218. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement