Add nowinandroid benchmark
Contents of README.google:
Name: Now in Android App
URL: https://github.com/android/nowinandroid
Version: NA
Revision: 1d2029aa2c4273ff75a9239112f32800800bd26b
Date: Feb 20, 2024
License: Apache License 2.0
Fixes: b/308368445
Change-Id: Ib0def6ed3cc2304327123981339394580e82c5c4
diff --git a/.gitignore b/.gitignore
index a3f84c9..ba2303e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -270,6 +270,8 @@
third_party/opensource-apps/wikipedia
third_party/opensource-apps/wikipedia.tar.gz
third_party/opensource-apps/android/compose-samples/*
+third_party/opensource-apps/android/nowinandroid
+third_party/opensource-apps/android/nowinandroid.tar.gz
third_party/proguard/*
third_party/proguardsettings.tar.gz
third_party/proguardsettings/
diff --git a/src/test/java/com/android/tools/r8/R8TestBuilder.java b/src/test/java/com/android/tools/r8/R8TestBuilder.java
index 51cab44..5184c82 100644
--- a/src/test/java/com/android/tools/r8/R8TestBuilder.java
+++ b/src/test/java/com/android/tools/r8/R8TestBuilder.java
@@ -953,6 +953,11 @@
return addProgramClassFileData(testResource.getRClass().getClassFileData());
}
+ public T setAndroidResourcesFromPath(Path input) throws IOException {
+ return setAndroidResourcesFromPath(
+ input, getState().getNewTempFile("resourceshrinkeroutput.zip"));
+ }
+
public T setAndroidResourcesFromPath(Path input, Path output) {
resourceShrinkerOutput = output;
getBuilder()
diff --git a/src/test/java/com/android/tools/r8/R8TestCompileResult.java b/src/test/java/com/android/tools/r8/R8TestCompileResult.java
index 7454ce3..ef7013b 100644
--- a/src/test/java/com/android/tools/r8/R8TestCompileResult.java
+++ b/src/test/java/com/android/tools/r8/R8TestCompileResult.java
@@ -11,6 +11,7 @@
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.androidresources.AndroidResourceTestingUtils;
import com.android.tools.r8.androidresources.AndroidResourceTestingUtils.ResourceTableInspector;
+import com.android.tools.r8.benchmarks.BenchmarkResults;
import com.android.tools.r8.dexsplitter.SplitterTestBase.SplitRunner;
import com.android.tools.r8.profile.art.model.ExternalArtProfile;
import com.android.tools.r8.profile.art.utils.ArtProfileInspector;
@@ -27,6 +28,7 @@
import com.android.tools.r8.utils.graphinspector.GraphInspector;
import java.io.IOException;
import java.io.UncheckedIOException;
+import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.List;
@@ -70,6 +72,11 @@
this.resourceShrinkerOutputForFeatures = resourceShrinkerOutputForFeatures;
}
+ public R8TestCompileResult benchmarkResourceSize(BenchmarkResults results) throws IOException {
+ results.addCodeSizeResult(Files.size(resourceShrinkerOutput));
+ return self();
+ }
+
@Override
public R8TestCompileResult self() {
return this;
diff --git a/src/test/java/com/android/tools/r8/TestCompileResult.java b/src/test/java/com/android/tools/r8/TestCompileResult.java
index 4c2d6a8..24cd012 100644
--- a/src/test/java/com/android/tools/r8/TestCompileResult.java
+++ b/src/test/java/com/android/tools/r8/TestCompileResult.java
@@ -24,13 +24,11 @@
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.AndroidApp;
-import com.android.tools.r8.utils.Box;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.ThrowingConsumer;
import com.android.tools.r8.utils.TriFunction;
-import com.android.tools.r8.utils.ZipUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.google.common.collect.ImmutableList;
@@ -708,18 +706,8 @@
app, runtime, ToolHelper.runDex2OatRaw(jarFile, oatFile, vm), state);
}
- public CR benchmarkCodeSize(BenchmarkResults results) throws IOException {
- Path out = writeToZip();
- Box<Long> size = new Box<>(0L);
- ZipUtils.iter(
- out,
- (entry, stream) -> {
- if ((getBackend().isDex() && entry.getName().endsWith(".dex"))
- || getBackend().isCf() && entry.getName().endsWith(".class")) {
- size.set(size.get() + entry.getSize());
- }
- });
- results.addCodeSizeResult(size.get());
+ public CR benchmarkCodeSize(BenchmarkResults results) throws IOException, ResourceException {
+ results.addCodeSizeResult(app.applicationSize());
return self();
}
}
diff --git a/src/test/java/com/android/tools/r8/benchmarks/BenchmarkCollection.java b/src/test/java/com/android/tools/r8/benchmarks/BenchmarkCollection.java
index 5c30550..a8cdc56 100644
--- a/src/test/java/com/android/tools/r8/benchmarks/BenchmarkCollection.java
+++ b/src/test/java/com/android/tools/r8/benchmarks/BenchmarkCollection.java
@@ -5,6 +5,7 @@
import static java.util.Collections.emptyList;
+import com.android.tools.r8.benchmarks.appdumps.NowInAndroidBenchmarks;
import com.android.tools.r8.benchmarks.appdumps.TiviBenchmarks;
import com.android.tools.r8.benchmarks.desugaredlib.L8Benchmark;
import com.android.tools.r8.benchmarks.desugaredlib.LegacyDesugaredLibraryBenchmark;
@@ -49,6 +50,7 @@
HelloWorldBenchmark.configs().forEach(collection::addBenchmark);
LegacyDesugaredLibraryBenchmark.configs().forEach(collection::addBenchmark);
L8Benchmark.configs().forEach(collection::addBenchmark);
+ NowInAndroidBenchmarks.configs().forEach(collection::addBenchmark);
TiviBenchmarks.configs().forEach(collection::addBenchmark);
RetraceStackTraceBenchmark.configs().forEach(collection::addBenchmark);
return collection;
diff --git a/src/test/java/com/android/tools/r8/benchmarks/BenchmarkCollectionPrinter.java b/src/test/java/com/android/tools/r8/benchmarks/BenchmarkCollectionPrinter.java
index 1a26aa7..a0a073a 100644
--- a/src/test/java/com/android/tools/r8/benchmarks/BenchmarkCollectionPrinter.java
+++ b/src/test/java/com/android/tools/r8/benchmarks/BenchmarkCollectionPrinter.java
@@ -6,10 +6,12 @@
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.utils.CollectionUtils;
+import com.android.tools.r8.utils.IterableUtils;
import com.android.tools.r8.utils.ListUtils;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.StringUtils.BraceType;
import com.google.common.base.Strings;
+import com.google.common.collect.Sets;
import com.google.common.hash.Hasher;
import com.google.common.hash.Hashing;
import java.io.IOException;
@@ -25,6 +27,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.function.Function;
public class BenchmarkCollectionPrinter {
@@ -143,16 +146,18 @@
private void printGroupBenchmarkBlock(
String benchmarkName, List<BenchmarkConfig> benchmarkVariants) throws IOException {
String suite = BenchmarkConfig.getCommonSuite(benchmarkVariants).getDartName();
+ Map<String, Set<BenchmarkMetric>> subBenchmarks =
+ BenchmarkConfig.getCommonSubBenchmarks(benchmarkVariants);
+ Set<BenchmarkMetric> metrics =
+ Sets.newLinkedHashSet(IterableUtils.flatMap(subBenchmarks.values(), Function.identity()));
printSemi("final name = " + quote(benchmarkName));
- printSemi("final benchmark = GroupBenchmark(name, [])");
+ printSemi("final benchmark = GroupBenchmark(name, " + prettyMetrics(metrics) + ")");
BenchmarkTimeout timeout = BenchmarkConfig.getCommonTimeout(benchmarkVariants);
if (timeout != null) {
printSemi("final timeout = const Duration(seconds: " + timeout.asSeconds() + ")");
printSemi("ExecutionManagement.addTimeoutConstraint(timeout, benchmark: benchmark)");
}
printBenchmarkVariantOptionBlock(benchmarkVariants);
- Map<String, Set<BenchmarkMetric>> subBenchmarks =
- BenchmarkConfig.getCommonSubBenchmarks(benchmarkVariants);
Collection<String> subNames = CollectionUtils.sort(subBenchmarks.keySet(), String::compareTo);
for (String subName : subNames) {
scopeBraces(
@@ -229,7 +234,8 @@
}
private static Path getJdkHome() throws IOException {
- ProcessBuilder builder = new ProcessBuilder("python3", "tools/jdk.py");
+ ProcessBuilder builder =
+ new ProcessBuilder("python3", ToolHelper.getProjectRoot() + "tools/jdk.py");
ProcessResult result = ToolHelper.runProcess(builder, QUIET);
if (result.exitCode != 0) {
throw new BenchmarkConfigError("Unexpected failure to determine jdk home: " + result);
diff --git a/src/test/java/com/android/tools/r8/benchmarks/BenchmarkResultsCollection.java b/src/test/java/com/android/tools/r8/benchmarks/BenchmarkResultsCollection.java
index e9b205d..29f0c78 100644
--- a/src/test/java/com/android/tools/r8/benchmarks/BenchmarkResultsCollection.java
+++ b/src/test/java/com/android/tools/r8/benchmarks/BenchmarkResultsCollection.java
@@ -20,12 +20,14 @@
(name, metrics) -> results.put(name, new BenchmarkResultsSingle(name, metrics)));
}
+ @Override
public void addRuntimeResult(long result) {
throw new BenchmarkConfigError(
"Unexpected attempt to add a runtime result to a the root of a benchmark with"
+ " sub-benchmarks");
}
+ @Override
public void addCodeSizeResult(long result) {
throw new BenchmarkConfigError(
"Unexpected attempt to add a runtime result to a the root of a benchmark with"
diff --git a/src/test/java/com/android/tools/r8/benchmarks/appdumps/AppDumpBenchmarkBuilder.java b/src/test/java/com/android/tools/r8/benchmarks/appdumps/AppDumpBenchmarkBuilder.java
index f69b30f..7e2a677 100644
--- a/src/test/java/com/android/tools/r8/benchmarks/appdumps/AppDumpBenchmarkBuilder.java
+++ b/src/test/java/com/android/tools/r8/benchmarks/appdumps/AppDumpBenchmarkBuilder.java
@@ -36,7 +36,7 @@
private String name;
private BenchmarkDependency dumpDependency;
private int fromRevision = -1;
- private List<String> programPackages = new ArrayList<>();
+ private final List<String> programPackages = new ArrayList<>();
public void verify() {
if (name == null) {
@@ -97,6 +97,22 @@
.build();
}
+ public BenchmarkConfig buildR8WithResourceShrinking() {
+ verify();
+ return BenchmarkConfig.builder()
+ .setName(name)
+ .setTarget(BenchmarkTarget.R8_NON_COMPAT)
+ .setSuite(BenchmarkSuite.OPENSOURCE_BENCHMARKS)
+ .setMethod(runR8WithResourceShrinking(this))
+ .setFromRevision(fromRevision)
+ .addDependency(dumpDependency)
+ .addSubBenchmark(nameForCodePart(), BenchmarkMetric.CodeSize)
+ .addSubBenchmark(nameForRuntimePart(), BenchmarkMetric.RunTimeRaw)
+ .addSubBenchmark(nameForResourcePart(), BenchmarkMetric.CodeSize)
+ .setTimeout(10, TimeUnit.MINUTES)
+ .build();
+ }
+
public BenchmarkConfig buildIncrementalD8() {
verify();
if (programPackages.isEmpty()) {
@@ -132,6 +148,10 @@
.build();
}
+ private String nameForCodePart() {
+ return name + "Code";
+ }
+
private String nameForLibraryPart() {
return name + "Library";
}
@@ -140,12 +160,26 @@
return name + "Program";
}
+ private String nameForResourcePart() {
+ return name + "Resource";
+ }
+
+ private String nameForRuntimePart() {
+ return name + "Runtime";
+ }
+
private String nameForMergePart() {
return name + "Merge";
}
private CompilerDump getExtractedDump(BenchmarkEnvironment environment) throws IOException {
- Path dump = dumpDependency.getRoot(environment).resolve("dump_app.zip");
+ return getExtractedDump(environment, false);
+ }
+
+ private CompilerDump getExtractedDump(
+ BenchmarkEnvironment environment, boolean enableResourceShrinking) throws IOException {
+ String dumpName = enableResourceShrinking ? "dump_app_res.zip" : "dump_app.zip";
+ Path dump = dumpDependency.getRoot(environment).resolve(dumpName);
return CompilerDump.fromArchive(dump, environment.getTemp().newFolder().toPath());
}
@@ -159,12 +193,22 @@
}
private static BenchmarkMethod runR8(AppDumpBenchmarkBuilder builder) {
+ return internalRunR8(builder, false);
+ }
+
+ private static BenchmarkMethod runR8WithResourceShrinking(AppDumpBenchmarkBuilder builder) {
+ return internalRunR8(builder, true);
+ }
+
+ private static BenchmarkMethod internalRunR8(
+ AppDumpBenchmarkBuilder builder, boolean enableResourceShrinking) {
return environment ->
BenchmarkBase.runner(environment.getConfig())
.setWarmupIterations(1)
.run(
results -> {
- CompilerDump dump = builder.getExtractedDump(environment);
+ CompilerDump dump =
+ builder.getExtractedDump(environment, enableResourceShrinking);
DumpOptions dumpProperties = dump.getBuildProperties();
TestBase.testForR8(environment.getTemp(), Backend.DEX)
.addProgramFiles(dump.getProgramArchive())
@@ -180,8 +224,21 @@
.addOptionsModification(
options ->
options.getOpenClosedInterfacesOptions().suppressAllOpenInterfaces())
- .benchmarkCompile(results)
- .benchmarkCodeSize(results);
+ .applyIf(
+ enableResourceShrinking,
+ b ->
+ b.enableOptimizedShrinking()
+ .setAndroidResourcesFromPath(dump.getAndroidResources()))
+ .applyIf(
+ enableResourceShrinking,
+ r ->
+ r.benchmarkCompile(
+ results.getSubResults(builder.nameForRuntimePart()))
+ .benchmarkCodeSize(
+ results.getSubResults(builder.nameForCodePart()))
+ .benchmarkResourceSize(
+ results.getSubResults(builder.nameForResourcePart())),
+ r -> r.benchmarkCompile(results).benchmarkCodeSize(results));
});
}
diff --git a/src/test/java/com/android/tools/r8/benchmarks/appdumps/NowInAndroidBenchmarks.java b/src/test/java/com/android/tools/r8/benchmarks/appdumps/NowInAndroidBenchmarks.java
new file mode 100644
index 0000000..c401bad
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/benchmarks/appdumps/NowInAndroidBenchmarks.java
@@ -0,0 +1,51 @@
+// Copyright (c) 2024, 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.appdumps;
+
+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.google.common.collect.ImmutableList;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class NowInAndroidBenchmarks extends BenchmarkBase {
+
+ private static final Path dump =
+ Paths.get(ToolHelper.THIRD_PARTY_DIR, "opensource-apps", "android", "nowinandroid");
+
+ public NowInAndroidBenchmarks(BenchmarkConfig config, TestParameters parameters) {
+ super(config, parameters);
+ }
+
+ @Parameters(name = "{0}")
+ public static List<Object[]> data() {
+ return parametersFromConfigs(configs());
+ }
+
+ public static List<BenchmarkConfig> configs() {
+ return ImmutableList.of(
+ AppDumpBenchmarkBuilder.builder()
+ .setName("NowInAndroidApp")
+ .setDumpDependencyPath(dump)
+ .setFromRevision(16017)
+ .buildBatchD8(),
+ AppDumpBenchmarkBuilder.builder()
+ .setName("NowInAndroidApp")
+ .setDumpDependencyPath(dump)
+ .setFromRevision(16017)
+ .buildR8(),
+ AppDumpBenchmarkBuilder.builder()
+ .setName("NowInAndroidAppWithResourceShrinking")
+ .setDumpDependencyPath(dump)
+ .setFromRevision(16017)
+ .buildR8WithResourceShrinking());
+ }
+}
diff --git a/third_party/opensource-apps/android/nowinandroid.tar.gz.sha1 b/third_party/opensource-apps/android/nowinandroid.tar.gz.sha1
new file mode 100644
index 0000000..818d960
--- /dev/null
+++ b/third_party/opensource-apps/android/nowinandroid.tar.gz.sha1
@@ -0,0 +1 @@
+a7939d3a61e72f091071f19ad8532a0ea388a607
\ No newline at end of file