@@ -68,10 +68,11 @@ object Main extends Logging {
68
68
" Query the database for test results and print them." ) {
69
69
val pivot = Opts .options[String ](" pivot" , help = " Parameter names to pivot in table output." ).map(_.toList).orElse(Opts (Nil ))
70
70
val raw = Opts .flag(" raw" , " Print raw JSON data instead of a table." ).orFalse
71
- (runs, benchs, extract, regex, scorePrecision, pivot, raw).mapN { case (runs, benchs, extract, regex, sp, pivot, raw) =>
71
+ val metric = Opts .option[String ](" metric" , " Secondary metric to report rather than the primary, e.g. ·gc.alloc.rate.norm" ).orNone
72
+ (runs, benchs, extract, regex, scorePrecision, pivot, raw, metric).mapN { case (runs, benchs, extract, regex, sp, pivot, raw, metric) =>
72
73
{ go =>
73
74
if (raw && pivot.nonEmpty) logger.error(" Cannot pivot in raw output mode." )
74
- else queryResults(go, runs, benchs, extract, regex, sp, pivot, raw)
75
+ else queryResults(go, runs, benchs, extract, regex, sp, pivot, raw, metric )
75
76
}
76
77
}
77
78
}
@@ -80,8 +81,9 @@ object Main extends Logging {
80
81
val template = Opts .option[Path ](" template" , " HTML template containing file." ).orNone
81
82
val out = Opts .option[Path ](" out" , short = " o" , help = " Output file to generate, or '-' for stdout." ).orNone
82
83
val pivot = Opts .options[String ](" pivot" , help = " Parameter names to combine in a chart." ).map(_.toList).orElse(Opts (Nil ))
83
- (runs, benchs, extract, regex, scorePrecision, pivot, template, out).mapN { case (runs, benchs, extract, regex, sp, pivot, template, out) =>
84
- createChart(_, runs, benchs, extract, regex, sp, pivot, template, out, args)
84
+ val metric = Opts .option[String ](" metric" , " Secondary metric to report rather than the primary, e.g. ·gc.alloc.rate.norm" ).orNone
85
+ (runs, benchs, extract, regex, scorePrecision, pivot, metric, template, out).mapN { case (runs, benchs, extract, regex, sp, pivot, metric, template, out) =>
86
+ createChart(_, runs, benchs, extract, regex, sp, pivot, metric, template, out, args)
85
87
}
86
88
}
87
89
@@ -169,12 +171,16 @@ object Main extends Logging {
169
171
}
170
172
}
171
173
172
- def queryResults (go : GlobalOptions , runs : Seq [String ], benchs : Seq [String ], extract : Seq [String ], regex : Boolean , scorePrecision : Int , pivot : Seq [String ], raw : Boolean ): Unit = try {
174
+ def queryResults (go : GlobalOptions , runs : Seq [String ], benchs : Seq [String ], extract : Seq [String ], regex : Boolean , scorePrecision : Int , pivot : Seq [String ], raw : Boolean , metric : Option [ String ] ): Unit = try {
173
175
new Global (go).use { g =>
174
176
val multi = runs.size > 1
175
177
val allRs = g.dao.run(g.dao.checkVersion andThen g.dao.queryResults(runs))
176
178
.map { case (rr, runId) => RunResult .fromDb(rr, runId, multi) }
177
179
val rs = RunResult .extract(extract, regex, RunResult .filterByName(benchs, allRs)).toSeq
180
+ val benchmarkLabel = metric match {
181
+ case Some (id) => s " Benchmark [ $id] "
182
+ case None => " Benchmark"
183
+ }
178
184
if (raw) {
179
185
print(" [" )
180
186
rs.zipWithIndex.foreach { case (r, idx) =>
@@ -200,22 +206,23 @@ object Main extends Logging {
200
206
paramNames.map(s => Format (Align .Right )),
201
207
Seq (Format (), Format (Align .Right ), Format (Align .Right ), Format (Align .Right ), Format ())
202
208
).flatten
203
- val header = ((" Benchmark " +: paramNames.map(s => s " ( $s) " )) ++ Vector (" Mode" , " Cnt" , " Score" , " Error" , " Units" )).map(formatHeader)
209
+ val header = ((benchmarkLabel +: paramNames.map(s => s " ( $s) " )) ++ Vector (" Mode" , " Cnt" , " Score" , " Error" , " Units" )).map(formatHeader)
204
210
val data = rs.iterator.map { r =>
211
+ val score = r.primaryMetricOr(metric)
205
212
Vector (
206
213
Seq (r.name),
207
214
paramNames.map(k => r.params.getOrElse(k, " " )),
208
215
Seq (r.db.mode, r.cnt,
209
- ScoreFormatter (r.primaryMetric. score, scorePrecision), ScoreFormatter (r.primaryMetric .scoreError, scorePrecision),
210
- r.primaryMetric .scoreUnit)
216
+ ScoreFormatter (score. score, scorePrecision), ScoreFormatter (score .scoreError, scorePrecision),
217
+ score .scoreUnit)
211
218
).flatten
212
219
}.toVector
213
220
val table = new TableFormatter (go).apply(columns, Vector (header, null ) ++ data)
214
221
table.foreach(println)
215
222
} else if (paramNames.length + pivotSet.size != allParamNames.length) {
216
223
logger.error(s " Illegal pivot parameters. " )
217
224
} else {
218
- val (pivoted, pivotSets) = RunResult .pivot(rs, pivot, paramNames)
225
+ val (pivoted, pivotSets) = RunResult .pivot(rs, pivot, paramNames, metric )
219
226
val columns = Vector (
220
227
Seq (Format ()),
221
228
paramNames.map(s => Format (Align .Right )),
@@ -230,23 +237,25 @@ object Main extends Logging {
230
237
Seq (" " ),
231
238
).flatten
232
239
val header2 = Vector (
233
- Seq (" Benchmark " ),
240
+ Seq (benchmarkLabel ),
234
241
paramNames.map(s => s " ( $s) " ),
235
242
Seq (" Mode" , " Cnt" ),
236
243
pivotSets.flatMap(_ => Seq (" Score" , " Error" )),
237
244
Seq (" Units" ),
238
245
).flatten.map(formatHeader)
239
246
val data = pivoted.iterator.map { case (r, pivotData) =>
240
247
val scoreData = pivotData.flatMap {
241
- case Some (rr) => Seq (ScoreFormatter (rr.primaryMetric.score, scorePrecision), ScoreFormatter (rr.primaryMetric.scoreError, scorePrecision))
248
+ case Some (rr) =>
249
+ val score = rr.primaryMetricOr(metric)
250
+ Seq (ScoreFormatter (score.score, scorePrecision), ScoreFormatter (score.scoreError, scorePrecision))
242
251
case None => Seq (null , null )
243
252
}
244
253
Vector (
245
254
Seq (r.name),
246
255
paramNames.map(k => r.params.getOrElse(k, " " )),
247
256
Seq (r.db.mode, r.cnt),
248
257
scoreData,
249
- Seq (r.primaryMetric .scoreUnit)
258
+ Seq (r.primaryMetricOr(metric) .scoreUnit)
250
259
).flatten
251
260
}.toVector
252
261
val table = new TableFormatter (go).apply(columns, Vector (header1, header2, null ) ++ data)
@@ -259,7 +268,7 @@ object Main extends Logging {
259
268
case ex : PatternSyntaxException => logger.error(ex.toString)
260
269
}
261
270
262
- def createChart (go : GlobalOptions , runs : Seq [String ], benchs : Seq [String ], extract : Seq [String ], regex : Boolean , scorePrecision : Int , pivot : Seq [String ], template : Option [Path ], out : Option [Path ], cmdLine : Array [String ]): Unit = {
271
+ def createChart (go : GlobalOptions , runs : Seq [String ], benchs : Seq [String ], extract : Seq [String ], regex : Boolean , scorePrecision : Int , pivot : Seq [String ], metric : Option [ String ], template : Option [Path ], out : Option [Path ], cmdLine : Array [String ]): Unit = {
263
272
new Global (go).use { g =>
264
273
val multi = runs.size > 1
265
274
val allRs = g.dao.run(g.dao.checkVersion andThen g.dao.queryResults(runs))
@@ -268,14 +277,14 @@ object Main extends Logging {
268
277
val allParamNames = rs.flatMap(_.params.keys).distinct.toVector
269
278
val pivotSet = pivot.toSet
270
279
val paramNames = allParamNames.filterNot(pivotSet.contains)
271
- val gen = new GenerateCharts (go, scorePrecision)
280
+ val gen = new GenerateCharts (go, scorePrecision, metric )
272
281
val data =
273
282
if (pivot.isEmpty) gen.generate(rs)
274
283
else if (paramNames.length + pivotSet.size != allParamNames.length) {
275
284
logger.error(s " Illegal pivot parameters. " )
276
285
" "
277
286
} else {
278
- val (pivoted, pivotSets) = RunResult .pivot(rs, pivot, paramNames)
287
+ val (pivoted, pivotSets) = RunResult .pivot(rs, pivot, paramNames, metric )
279
288
gen.generatePivoted(pivoted, pivotSets, pivot, paramNames)
280
289
}
281
290
val templateHtml = template match {
0 commit comments