blob: 7346830d5efdd77730b9fa00a605376d614a1606 [file] [log] [blame]
Ian Zernydcb172e2022-02-22 15:36:45 +01001#!/usr/bin/env python3
Jean-Marie Henaffe4e36d12018-04-05 10:33:50 +02002# Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file
3# for details. All rights reserved. Use of this source code is governed by a
4# BSD-style license that can be found in the LICENSE file.
5
Jean-Marie Henaffe4e36d12018-04-05 10:33:50 +02006from __future__ import print_function
7import argparse
Rico Wind1f4172c2018-09-06 16:29:03 +02008import gradle
Jean-Marie Henaffe4e36d12018-04-05 10:33:50 +02009import os
Rico Wind49620922018-10-11 09:12:05 +020010import subprocess
Jean-Marie Henaffe4e36d12018-04-05 10:33:50 +020011import sys
12import utils
Jean-Marie Henaffe4e36d12018-04-05 10:33:50 +020013from enum import Enum
14
Jean-Marie Henaffe4e36d12018-04-05 10:33:50 +020015BENCHMARKS_ROOT_DIR = os.path.join(utils.REPO_ROOT, 'third_party', 'benchmarks')
16
17def parse_arguments():
18 parser = argparse.ArgumentParser(
19 description='Run D8 or DX on gradle apps located in'
20 ' third_party/benchmarks/.'
21 ' Report Golem-compatible RunTimeRaw values.')
Rico Wind23359232018-04-17 09:41:18 +020022 parser.add_argument('--skip_download',
Rico Wind834e7fc2018-04-16 14:24:52 +020023 help='Don\'t automatically pull down dependencies.',
24 default=False, action='store_true')
Jean-Marie Henaffe4e36d12018-04-05 10:33:50 +020025 parser.add_argument('--tool',
26 choices=['dx', 'd8'],
27 required=True,
28 help='Compiler tool to use.')
Rico Wind834e7fc2018-04-16 14:24:52 +020029
Rico Windab38fb92018-04-06 16:10:52 +020030 parser.add_argument('--benchmark',
31 help='Which benchmark to run, default all')
Jean-Marie Henaffe4e36d12018-04-05 10:33:50 +020032 return parser.parse_args()
33
Jean-Marie Henaffe4e36d12018-04-05 10:33:50 +020034class Benchmark:
35 class Tools(Enum):
36 D8 = 1
37 DX = 2
38
39 class DesugarMode(Enum):
40 D8_DESUGARING = 1
41 DESUGAR_TOOL = 2
42
43 displayName = ""
44 rootDirPath = ""
45 appPath = ""
46 moduleName = ""
47 buildCommand = ""
48 cleanCommand = ""
Jean-Marie Henaff889dd942018-04-05 15:56:36 +020049 env = {}
Jean-Marie Henaffe4e36d12018-04-05 10:33:50 +020050
Rico Winde03b1a42018-04-06 16:14:40 +020051 def __init__(self, displayName, benchmarkDir, moduleName, buildCommand,
52 cleanCommand):
Jean-Marie Henaffe4e36d12018-04-05 10:33:50 +020053 self.displayName = displayName
Rico Winde03b1a42018-04-06 16:14:40 +020054 self.rootDirPath = os.path.join(BENCHMARKS_ROOT_DIR,
55 benchmarkDir.split(os.sep)[0])
Jean-Marie Henaffe4e36d12018-04-05 10:33:50 +020056 self.appPath = os.path.join(BENCHMARKS_ROOT_DIR, benchmarkDir)
57 self.moduleName = moduleName
58 self.buildCommand = buildCommand
59 self.cleanCommand = cleanCommand
Jean-Marie Henaff889dd942018-04-05 15:56:36 +020060 self.env = os.environ.copy()
Rico Winde03b1a42018-04-06 16:14:40 +020061 self.env["ANDROID_HOME"] = os.path.join(utils.REPO_ROOT, 'third_party',
62 'benchmarks', 'android-sdk')
Jean-Marie Henaffe4e36d12018-04-05 10:33:50 +020063
64 def RunGradle(self, command, tool, desugarMode):
65
66 args = ['-Dr8.root.dir=' + utils.REPO_ROOT, '--init-script',
67 os.path.join(BENCHMARKS_ROOT_DIR, 'init-script.gradle')]
68
69 if tool == self.Tools.D8:
70 args.append('-Dandroid.enableD8=true')
71 elif tool == self.Tools.DX:
72 args.append('-Dandroid.enableD8=false')
73 else:
74 raise AssertionError("Unknown tool: " + repr(tool))
75
76 if desugarMode == self.DesugarMode.D8_DESUGARING:
77 args.append('-Dandroid.enableDesugar=false')
78 elif desugarMode == self.DesugarMode.DESUGAR_TOOL:
79 args.append('-Dandroid.enableDesugar=true')
80 else:
81 raise AssertionError("Unknown desugar mode: " + repr(desugarMode))
Rico Wind49620922018-10-11 09:12:05 +020082 # Running with a daemon will give inconsistent results based on previous runs
83 # and if the golem runners restarted.
84 args.append('--no-daemon')
Jean-Marie Henaffe4e36d12018-04-05 10:33:50 +020085 args.extend(command)
86
Jean-Marie Henaff889dd942018-04-05 15:56:36 +020087 return gradle.RunGradleWrapperInGetOutput(args, self.appPath, env=self.env)
Jean-Marie Henaffe4e36d12018-04-05 10:33:50 +020088
89 def Build(self, tool, desugarMode):
90 return self.RunGradle(self.buildCommand, tool, desugarMode)
91
92 def Clean(self):
93 # tools and desugar mode not relevant for clean
Rico Winde03b1a42018-04-06 16:14:40 +020094 return self.RunGradle(self.cleanCommand,
95 self.Tools.D8,
96 self.DesugarMode.D8_DESUGARING)
Jean-Marie Henaffe4e36d12018-04-05 10:33:50 +020097
98 def EnsurePresence(self):
99 EnsurePresence(self.rootDirPath, self.displayName)
100
Jean-Marie Henaffe4e36d12018-04-05 10:33:50 +0200101def EnsurePresence(dir, displayName):
102 if not os.path.exists(dir) or os.path.getmtime(dir + '.tar.gz')\
103 < os.path.getmtime(dir + '.tar.gz.sha1'):
104 utils.DownloadFromX20(dir + '.tar.gz.sha1')
105 # Update the mtime of the tar file to make sure we do not run again unless
106 # there is an update.
107 os.utime(dir + '.tar.gz', None)
108 else:
109 print('test_gradle_benchmarks.py: benchmark {} is present'.format(displayName))
110
111def TaskFilter(taskname):
112 acceptedGradleTasks = [
113 'dex',
114 'Dex',
115 'proguard',
116 'Proguard',
117 'kotlin',
118 'Kotlin',
119 ]
120
121 return any(namePattern in taskname for namePattern in acceptedGradleTasks)
122
Morten Krogh-Jespersen254805e2022-06-03 09:32:42 +0200123def PrintBuildTime(benchmark, stdOut):
Jean-Marie Henaffe4e36d12018-04-05 10:33:50 +0200124 for line in stdOut.splitlines():
125 if 'BENCH' in line and benchmark.moduleName in line:
126 commaSplit = line.split(',')
127 assert len(commaSplit) == 3
128
129 # Keep only module that have been configured to use R8
130 if benchmark.moduleName + ':' not in commaSplit[1]:
131 continue
132
133 # remove <module-name> + ':'
134 taskName = commaSplit[1][(len(benchmark.moduleName) + 1):]
135
136 # Just a temporary assumption.
Rico Winde03b1a42018-04-06 16:14:40 +0200137 # This means we have submodules, so we'll need to check their
138 # configuration so that the right r8/d8 is taken. For now it shouldn't
139 # be the case.
Jean-Marie Henaffe4e36d12018-04-05 10:33:50 +0200140 assert taskName.find(':') == -1, taskName
141
Jean-Marie Henaffe4e36d12018-04-05 10:33:50 +0200142 if TaskFilter(taskName):
Rico Winde03b1a42018-04-06 16:14:40 +0200143 # taskName looks like:
144 # transformClassesWithDexBuilderForDevelopmentDebug
145 # we don't want unimportant information in UI, so we strip it down to:
146 # ClassesDexBuilderDevelopment
147 # Output example:
148 # SantaTracker-ClassesDexBuilderDevelopment(RunTimeRaw): 748 ms
149 assert taskName.startswith('transform')
150 taskName = taskName[len('transform'):]
151 taskName = taskName.replace('With', '')
152 taskName = taskName.replace('For', '')
153 taskName = taskName.replace('Default', '')
154 benchmarkName = benchmark.displayName + '-' + taskName
155 print('{}(RunTimeRaw): {} ms'.format(benchmarkName, commaSplit[2]))
Jean-Marie Henaffe4e36d12018-04-05 10:33:50 +0200156
Jean-Marie Henaffe4e36d12018-04-05 10:33:50 +0200157def Main():
158 args = parse_arguments()
Jean-Marie Henaffe4e36d12018-04-05 10:33:50 +0200159 if args.tool == 'd8':
160 tool = Benchmark.Tools.D8
161 desugarMode = Benchmark.DesugarMode.D8_DESUGARING
162 else:
163 tool = Benchmark.Tools.DX
164 desugarMode = Benchmark.DesugarMode.DESUGAR_TOOL
165
166 buildTimeBenchmarks = [
167 Benchmark('AntennaPod',
168 os.path.join('antenna-pod', 'AntennaPod'),
169 ':app',
170 [':app:assembleDebug'],
171 ['clean']),
172 Benchmark('Maps',
173 'gradle-java-1.6',
174 ':maps',
Rico Winde03b1a42018-04-06 16:14:40 +0200175 [':maps:assembleDebug', '--settings-file',
176 'settings.gradle.maps'],
Jean-Marie Henaffe4e36d12018-04-05 10:33:50 +0200177 ['clean']),
178 Benchmark('Music2',
179 'gradle-java-1.6',
180 ':music2Old',
Rico Winde03b1a42018-04-06 16:14:40 +0200181 [':music2Old:assembleDebug', '--settings-file',
182 'settings.gradle.music2Old'],
Jean-Marie Henaffe4e36d12018-04-05 10:33:50 +0200183 ['clean']),
184 Benchmark('Velvet',
185 'gradle-java-1.6',
186 ':velvet',
Rico Winde03b1a42018-04-06 16:14:40 +0200187 [':velvet:assembleDebug', '--settings-file',
188 'settings.gradle.velvet'],
Jean-Marie Henaffe4e36d12018-04-05 10:33:50 +0200189 ['clean']),
190 Benchmark('SantaTracker',
191 'santa-tracker',
192 ':santa-tracker',
193 [':santa-tracker:assembleDebug'],
194 ['clean']),
195
196 # disabled for now, apparently because of b/74227571
197 # Benchmark('Tachiyomi',
198 # 'tachiyomi',
199 # ':app',
200 # ['assembleStandardDebug'],
201 # ['clean']),
202
203 Benchmark('WordPress',
204 'wordpress',
205 ':WordPress',
206 ['assembleVanillaDebug'],
207 ['clean']),
208
209 ]
Morten Krogh-Jespersen254805e2022-06-03 09:32:42 +0200210 if not args.skip_download:
Rico Wind834e7fc2018-04-16 14:24:52 +0200211 EnsurePresence(os.path.join('third_party', 'benchmarks', 'android-sdk'),
212 'android SDK')
213 EnsurePresence(os.path.join('third_party', 'gradle-plugin'),
214 'Android Gradle plugin')
Rico Windab38fb92018-04-06 16:10:52 +0200215 toRun = buildTimeBenchmarks
216 if args.benchmark:
217 toRun = [b for b in toRun if b.displayName == args.benchmark]
218 if len(toRun) != 1:
219 raise AssertionError("Unknown benchmark: " + args.benchmark)
220 for benchmark in toRun:
Rico Wind834e7fc2018-04-16 14:24:52 +0200221 if not args.skip_download:
222 benchmark.EnsurePresence()
Jean-Marie Henaffe4e36d12018-04-05 10:33:50 +0200223 benchmark.Clean()
224 stdOut = benchmark.Build(tool, desugarMode)
Morten Krogh-Jespersen254805e2022-06-03 09:32:42 +0200225 PrintBuildTime(benchmark, stdOut)
Jean-Marie Henaffe4e36d12018-04-05 10:33:50 +0200226
227
228if __name__ == '__main__':
229 sys.exit(Main())