blob: 51f9f3a9046ef7d658db3e5892e449f092f626de [file] [log] [blame]
// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.benchmarks;
import com.android.tools.r8.benchmarks.BenchmarkRunner.ResultMode;
import it.unimi.dsi.fastutil.longs.LongArrayList;
import it.unimi.dsi.fastutil.longs.LongList;
public class BenchmarkResults {
private final BenchmarkMetric runtimeMetric;
private final LongList runtimeResults = new LongArrayList();
private final LongList codeSizeResults = new LongArrayList();
public static BenchmarkResults create() {
return new BenchmarkResults(false);
}
public static BenchmarkResults createForWarmup() {
return new BenchmarkResults(true);
}
private BenchmarkResults(boolean isWarmupResults) {
this.runtimeMetric = isWarmupResults ? BenchmarkMetric.StartupTime : BenchmarkMetric.RunTimeRaw;
}
private boolean isWarmupResults() {
return runtimeMetric == BenchmarkMetric.StartupTime;
}
private String getName(BenchmarkConfig config) {
return config.getName();
}
public void addRuntimeResult(long result) {
runtimeResults.add(result);
}
public void addCodeSizeResult(long result) {
codeSizeResults.add(result);
}
private static void verifyMetric(BenchmarkMetric metric, boolean expected, boolean actual) {
if (expected != actual) {
throw new BenchmarkConfigError(
"Mismatched config and result for "
+ metric.name()
+ ". Expected by config: "
+ expected
+ ", but has result: "
+ actual);
}
}
private void verifyConfigAndResults(BenchmarkConfig config) {
verifyMetric(
BenchmarkMetric.RunTimeRaw,
config.getMetrics().contains(BenchmarkMetric.RunTimeRaw),
!runtimeResults.isEmpty());
verifyMetric(
BenchmarkMetric.CodeSize,
config.getMetrics().contains(BenchmarkMetric.CodeSize),
!codeSizeResults.isEmpty());
}
public static String prettyTime(long nanoTime) {
return "" + (nanoTime / 1000000) + " ms";
}
private void printRunTime(BenchmarkConfig config, long duration) {
String metric = runtimeMetric.name();
System.out.println(getName(config) + "(" + metric + "): " + prettyTime(duration));
}
private void printCodeSize(BenchmarkConfig config, long bytes) {
System.out.println(getName(config) + "(CodeSize): " + bytes);
}
public void printResults(ResultMode mode, BenchmarkConfig config) {
verifyConfigAndResults(config);
if (config.hasMetric(runtimeMetric)) {
long sum = runtimeResults.stream().mapToLong(l -> l).sum();
if (mode == ResultMode.SUM) {
printRunTime(config, sum);
} else if (mode == ResultMode.AVERAGE) {
printRunTime(config, sum / runtimeResults.size());
}
}
if (!isWarmupResults() && config.hasMetric(BenchmarkMetric.CodeSize)) {
long size = codeSizeResults.getLong(0);
for (int i = 1; i < codeSizeResults.size(); i++) {
if (size != codeSizeResults.getLong(i)) {
throw new RuntimeException(
"Unexpected code size difference: " + size + " and " + codeSizeResults.getLong(i));
}
}
printCodeSize(config, size);
}
}
}