1
+ package strawman .collection
2
+
3
+ import javax .imageio .ImageIO
4
+
5
+ import org .jfree .chart .JFreeChart
6
+ import org .jfree .chart .axis .{LogAxis , NumberAxis }
7
+ import org .jfree .chart .plot .XYPlot
8
+ import org .jfree .chart .renderer .xy .XYLineAndShapeRenderer
9
+ import org .jfree .data .xy .{XYSeries , XYSeriesCollection }
10
+ import play .api .libs .json .{JsObject , Json }
11
+ import sbt ._
12
+
13
+ object Bencharts {
14
+
15
+ /**
16
+ * Generate charts from the result of a JMH execution.
17
+ *
18
+ * Benchmarks that have the same name (e.g. `cons`) are grouped
19
+ * into a single chart with one series for each.
20
+ *
21
+ * @param jmhReport JMH results report
22
+ * @param targetDir Directory in which the images will be written
23
+ */
24
+ def apply (jmhReport : File , targetDir : File ): Unit = {
25
+ val json = Json .parse(IO .read(jmhReport))
26
+
27
+ json.as[List [JsObject ]]
28
+ .groupBy { result =>
29
+ val name = (result \ " benchmark" ).as[String ]
30
+ val benchmark = name.reverse.takeWhile(_ != '.' ).reverse
31
+ benchmark // Benchmark name (e.g. "cons", "foreach", "map")
32
+ }
33
+ .foreach { case (benchmark, results) =>
34
+ val seriess =
35
+ results
36
+ // group by concrete collection type
37
+ .groupBy(result => (result \ " benchmark" ).as[String ].stripSuffix(benchmark))
38
+ .map { case (collectionType, iterations) =>
39
+ val xySeries = new XYSeries (collectionType)
40
+ // each benchmark has been run with several collection sizes (8, 64, 512, etc.)
41
+ // we add a point for each of these iterations
42
+ for (iteration <- iterations) {
43
+ xySeries.add(
44
+ (iteration \ " params" \ " size" ).as[String ].toDouble,
45
+ (iteration \ " primaryMetric" \ " score" ).as[Double ]
46
+ )
47
+ }
48
+ xySeries
49
+ }
50
+
51
+ val xAxis = new LogAxis (" Size" )
52
+ xAxis.setBase(2 )
53
+ xAxis.setStandardTickUnits(NumberAxis .createIntegerTickUnits())
54
+ val yAxis = new LogAxis (" Execution time (lower is better)" )
55
+
56
+ val col = new XYSeriesCollection ()
57
+ for (series <- seriess) {
58
+ col.addSeries(series)
59
+ }
60
+
61
+ val plot = new XYPlot (
62
+ col,
63
+ xAxis, yAxis,
64
+ new XYLineAndShapeRenderer (true , true )
65
+ )
66
+
67
+ val chart = new JFreeChart (
68
+ benchmark,
69
+ JFreeChart .DEFAULT_TITLE_FONT ,
70
+ plot,
71
+ true
72
+ )
73
+
74
+ ImageIO .write(
75
+ chart.createBufferedImage(640 , 480 ),
76
+ " png" ,
77
+ targetDir / s " $benchmark.png "
78
+ )
79
+
80
+ }
81
+ }
82
+
83
+ }
0 commit comments