blob: f436c26857a07c3b62f2293e609ff54379927513 [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 boolean isWarmupResults;
private final LongList runtimeRawResults = 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.isWarmupResults = isWarmupResults;
}
private String getName(BenchmarkConfig config) {
return isWarmupResults ? config.getWarmupName() : config.getName();
}
public void addRuntimeRawResult(long result) {
runtimeRawResults.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),
!runtimeRawResults.isEmpty());
verifyMetric(
BenchmarkMetric.CodeSize,
config.getMetrics().contains(BenchmarkMetric.CodeSize),
!codeSizeResults.isEmpty());
}
public static String prettyTime(long nanoTime) {
return "" + (nanoTime / 1000000) + "ms";
}
private void printRunTimeRaw(BenchmarkConfig config, long duration) {
System.out.println(getName(config) + "(RunTimeRaw): " + 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(BenchmarkMetric.RunTimeRaw)) {
long sum = runtimeRawResults.stream().mapToLong(l -> l).sum();
if (mode == ResultMode.SUM) {
printRunTimeRaw(config, sum);
} else if (mode == ResultMode.AVERAGE) {
printRunTimeRaw(config, sum / runtimeRawResults.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);
}
}
}