blob: bbcfb5d6fbfb21e517587419832cf176cd1db0a5 [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.retrace;
import static com.android.tools.r8.ToolHelper.shouldRunSlowTests;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assume.assumeTrue;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.benchmarks.BenchmarkBase;
import com.android.tools.r8.benchmarks.BenchmarkConfig;
import com.android.tools.r8.benchmarks.BenchmarkDependency;
import com.android.tools.r8.benchmarks.BenchmarkEnvironment;
import com.android.tools.r8.benchmarks.BenchmarkMethod;
import com.android.tools.r8.benchmarks.BenchmarkRunner;
import com.android.tools.r8.benchmarks.BenchmarkTarget;
import com.android.tools.r8.retrace.MappingSupplier;
import com.android.tools.r8.retrace.PartitionMappingSupplier;
import com.android.tools.r8.retrace.ProguardMapProducer;
import com.android.tools.r8.retrace.ProguardMappingSupplier;
import com.android.tools.r8.retrace.Retrace;
import com.android.tools.r8.retrace.RetraceCommand;
import com.android.tools.r8.utils.FileUtils;
import com.google.common.collect.ImmutableList;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
/** Example of setting up a benchmark based on the testing infrastructure. */
@RunWith(Parameterized.class)
public class RetraceStackTraceBenchmark extends BenchmarkBase {
private static final BenchmarkDependency benchmarkDependency =
new BenchmarkDependency(
"retraceBenchmark", "retrace_benchmark", Paths.get(ToolHelper.THIRD_PARTY_DIR));
@Parameters(name = "{0}")
public static List<Object[]> data() {
return parametersFromConfigs(configs());
}
public RetraceStackTraceBenchmark(BenchmarkConfig config, TestParameters parameters) {
super(config, parameters);
}
/** Static method to add benchmarks to the benchmark collection. */
public static List<BenchmarkConfig> configs() {
return ImmutableList.<BenchmarkConfig>builder()
.add(
BenchmarkConfig.builder()
.setName("R8")
.setTarget(BenchmarkTarget.RETRACE)
.measureRunTime()
.setMethod(benchmarkRetraceLegacy("r8lib.jar.map"))
.setFromRevision(12266)
.measureWarmup()
.addDependency(benchmarkDependency)
.build())
.add(
BenchmarkConfig.builder()
.setName("R8-250MB-DISK")
.setTarget(BenchmarkTarget.RETRACE)
.measureRunTime()
.setMethod(benchmarkRetraceFromDisk("r8lib-250MB.jar.map"))
.setFromRevision(12266)
.measureWarmup()
.addDependency(benchmarkDependency)
.build())
.add(
BenchmarkConfig.builder()
.setName("R8-250MB-MEM")
.setTarget(BenchmarkTarget.RETRACE)
.measureRunTime()
.setMethod(benchmarkRetraceFromMemory("r8lib-250MB.jar.map"))
.setFromRevision(12266)
.measureWarmup()
.addDependency(benchmarkDependency)
.build())
.add(
BenchmarkConfig.builder()
.setName("R8-250MB-PARTITION")
.setTarget(BenchmarkTarget.RETRACE)
.measureRunTime()
.setMethod(benchmarkRetraceFromPartition("r8lib-250MB.jar.map.partition"))
.setFromRevision(12266)
.measureWarmup()
.addDependency(benchmarkDependency)
.build())
.add(
BenchmarkConfig.builder()
.setName("R8-500MB-DISK")
.setTarget(BenchmarkTarget.RETRACE)
.measureRunTime()
.setMethod(benchmarkRetraceFromDisk("r8lib-500MB.jar.map"))
.setFromRevision(12266)
.measureWarmup()
.addDependency(benchmarkDependency)
.build())
.add(
BenchmarkConfig.builder()
.setName("R8-500MB-MEM")
.setTarget(BenchmarkTarget.RETRACE)
.measureRunTime()
.setMethod(benchmarkRetraceFromMemory("r8lib-500MB.jar.map"))
.setFromRevision(12266)
.measureWarmup()
.addDependency(benchmarkDependency)
.build())
.add(
BenchmarkConfig.builder()
.setName("R8-500MB-PARTITION")
.setTarget(BenchmarkTarget.RETRACE)
.measureRunTime()
.setMethod(benchmarkRetraceFromPartition("r8lib-500MB.jar.map.partition"))
.setFromRevision(12266)
.measureWarmup()
.addDependency(benchmarkDependency)
.build())
.add(
BenchmarkConfig.builder()
.setName("R8-750MB-DISK")
.setTarget(BenchmarkTarget.RETRACE)
.measureRunTime()
.setMethod(benchmarkRetraceFromDisk("r8lib-750MB.jar.map"))
.setFromRevision(12266)
.measureWarmup()
.addDependency(benchmarkDependency)
.build())
.add(
BenchmarkConfig.builder()
.setName("R8-750MB-MEM")
.setTarget(BenchmarkTarget.RETRACE)
.measureRunTime()
.setMethod(benchmarkRetraceFromMemory("r8lib-750MB.jar.map"))
.setFromRevision(12266)
.measureWarmup()
.addDependency(benchmarkDependency)
.build())
.add(
BenchmarkConfig.builder()
.setName("R8-750MB-PARTITION")
.setTarget(BenchmarkTarget.RETRACE)
.measureRunTime()
.setMethod(benchmarkRetraceFromPartition("r8lib-750MB.jar.map.partition"))
.setFromRevision(12266)
.measureWarmup()
.addDependency(benchmarkDependency)
.build())
.add(
BenchmarkConfig.builder()
.setName("R8-1GB-DISK")
.setTarget(BenchmarkTarget.RETRACE)
.measureRunTime()
.setMethod(benchmarkRetraceFromDisk("r8lib-1GB.jar.map"))
.setFromRevision(12266)
.measureWarmup()
.addDependency(benchmarkDependency)
.build())
.add(
BenchmarkConfig.builder()
.setName("R8-1GB-MEM")
.setTarget(BenchmarkTarget.RETRACE)
.measureRunTime()
.setMethod(benchmarkRetraceFromMemory("r8lib-1GB.jar.map"))
.setFromRevision(12266)
.measureWarmup()
.addDependency(benchmarkDependency)
.build())
.add(
BenchmarkConfig.builder()
.setName("R8-1GB-PARTITION")
.setTarget(BenchmarkTarget.RETRACE)
.measureRunTime()
.setMethod(benchmarkRetraceFromPartition("r8lib-1GB.jar.map.partition"))
.setFromRevision(12266)
.measureWarmup()
.addDependency(benchmarkDependency)
.build())
.build();
}
public static BenchmarkMethod benchmarkRetraceLegacy(String mappingFileName) {
return internalBenchmarkRetrace(
mappingFileName,
false,
false,
environment ->
BenchmarkRunner.runner(environment).reportResultSum().setBenchmarkIterations(4));
}
public static BenchmarkMethod benchmarkRetraceFromDisk(String mappingFileName) {
return internalBenchmarkRetrace(
mappingFileName,
false,
false,
environment ->
BenchmarkRunner.runner(environment).reportResultAverage().setBenchmarkIterations(5));
}
public static BenchmarkMethod benchmarkRetraceFromMemory(String mappingFileName) {
return internalBenchmarkRetrace(
mappingFileName,
true,
false,
environment ->
BenchmarkRunner.runner(environment).reportResultAverage().setBenchmarkIterations(5));
}
public static BenchmarkMethod benchmarkRetraceFromPartition(String mappingFileName) {
return internalBenchmarkRetrace(
mappingFileName,
false,
true,
environment ->
BenchmarkRunner.runner(environment).reportResultAverage().setBenchmarkIterations(5));
}
public static BenchmarkMethod internalBenchmarkRetrace(
String mappingFileName,
boolean inMemoryMappingFile,
boolean partitionedMappingFile,
Function<BenchmarkEnvironment, BenchmarkRunner> runnerFactory) {
return environment ->
runnerFactory
.apply(environment)
.setWarmupIterations(1)
.run(
results -> {
Path dependencyRoot = benchmarkDependency.getRoot(environment);
Path mappingFile = dependencyRoot.resolve(mappingFileName);
byte[] mappingFileContents =
inMemoryMappingFile
? FileUtils.readTextFile(mappingFile).getBytes(UTF_8)
: null;
List<String> stackTrace =
Files.readAllLines(dependencyRoot.resolve("stacktrace.txt"));
List<String> retraced = new ArrayList<>();
long start = System.nanoTime();
Retrace.run(
RetraceCommand.builder()
.setMappingSupplier(
createMappingSupplier(
mappingFile, mappingFileContents, partitionedMappingFile))
.setStackTrace(stackTrace)
.setRetracedStackTraceConsumer(retraced::addAll)
.build());
long end = System.nanoTime();
// Add a simple check to ensure that we do not, in case of invalid retracing,
// record an optimal benchmark result.
if (retraced.size() < stackTrace.size()) {
throw new RuntimeException("Unexpected missing lines in retraced result");
}
results.addRuntimeResult(end - start);
// Do not make subsequent iterations pay for the memory allocated by this
// iteration.
System.gc();
System.gc();
});
}
private static MappingSupplier<?> createMappingSupplier(
Path mappingFile, byte[] mappingFileContents, boolean partitionedMappingFile)
throws IOException {
if (partitionedMappingFile) {
return PartitionMappingSupplier.fromPath(mappingFile);
}
return ProguardMappingSupplier.builder()
.setProguardMapProducer(
mappingFileContents != null
? ProguardMapProducer.fromBytes(mappingFileContents)
: ProguardMapProducer.fromPath(mappingFile))
.setLoadAllDefinitions(false)
.build();
}
@Test
@Override
public void testBenchmarks() throws Exception {
assumeTrue(shouldRunSlowTests());
super.testBenchmarks();
}
}