| #!/usr/bin/env python3 | |
| # Copyright (c) 2018, 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. | |
| # Script for running kotlin based benchmarks | |
| import optparse | |
| import os | |
| import subprocess | |
| import sys | |
| import toolhelper | |
| import utils | |
| BENCHMARK_ROOT = os.path.join(utils.REPO_ROOT, 'third_party', 'benchmarks', | |
| 'kotlin-benches') | |
| BENCHMARK_PATTERN = '{benchmark}/kotlin/perf/build/libs/perf-1.0-BENCH.jar' | |
| BENCHMARK_MAIN_CLASS = 'com.android.kt.bms.cli.Runner' | |
| ART = os.path.join(utils.TOOLS_DIR, 'linux', 'art', 'bin', 'art') | |
| PROGUARD_CONF = """ | |
| # From Android rules | |
| -keepclasseswithmembers public class * { | |
| public static void main(java.lang.String[]); | |
| } | |
| # Disable obfuscation to only focus on shrinking | |
| -dontobfuscate | |
| # Once we're ready for optimization, we might want to relax access modifiers. | |
| -allowaccessmodification | |
| """ | |
| DEVICE_TEMP='/data/local/temp/bench' | |
| def parse_options(): | |
| result = optparse.OptionParser() | |
| result.add_option('--api', | |
| help='Android api level', | |
| default='26', | |
| choices=['21', '22', '23', '24', '25', '26']) | |
| result.add_option('--benchmark', | |
| help='The benchmark to run', | |
| default='rgx', | |
| choices=['rgx', 'deltablue', 'sta', 'empty']) | |
| result.add_option('--use-device', | |
| help='Run the benchmark on an attaced device', | |
| default=False, action='store_true') | |
| return result.parse_args() | |
| def get_jar_for_benchmark(benchmark): | |
| return os.path.join(BENCHMARK_ROOT, | |
| BENCHMARK_PATTERN.format(benchmark=benchmark)) | |
| def run_art(dex): | |
| command = ['bash', ART, '-cp', dex, BENCHMARK_MAIN_CLASS] | |
| utils.PrintCmd(command) | |
| benchmark_output = subprocess.check_output(command) | |
| return get_result(benchmark_output) | |
| def adb(args): | |
| command = ['adb'] + args | |
| utils.PrintCmd(command) | |
| return subprocess.check_output(['adb'] + args) | |
| def get_result(output): | |
| # There is a lot of debug output, with the actual results being in the line with: | |
| # RESULTS,KtBench,KtBench,15719 | |
| # structure. | |
| for result in [s for s in output.splitlines() if s.startswith('RESULTS')]: | |
| return s.split('RESULTS,KtBench,KtBench,')[1] | |
| def run_art_device(dex): | |
| adb(['wait-for-device', 'root']) | |
| device_dst = os.path.join(DEVICE_TEMP, os.path.basename(dex)) | |
| adb(['push', dex, device_dst]) | |
| benchmark_output = adb(['shell', 'dalvikvm', '-cp', device_dst, BENCHMARK_MAIN_CLASS]) | |
| return get_result(benchmark_output) | |
| def Main(): | |
| (options, args) = parse_options() | |
| with utils.TempDir() as temp: | |
| dex_path = os.path.join(temp, "classes.jar") | |
| proguard_conf = os.path.join(temp, 'proguard.conf') | |
| with open(proguard_conf, 'w') as f: | |
| f.write(PROGUARD_CONF) | |
| benchmark_jar = get_jar_for_benchmark(options.benchmark) | |
| r8_args = [ | |
| '--lib', utils.get_android_jar(26), # Only works with api 26 | |
| '--output', dex_path, | |
| '--pg-conf', proguard_conf, | |
| '--min-api', str(options.api), | |
| benchmark_jar | |
| ] | |
| toolhelper.run('r8', r8_args, True) | |
| if options.use_device: | |
| result = run_art_device(dex_path) | |
| else: | |
| result = run_art(dex_path) | |
| print('Kotlin_{}(RunTimeRaw): {} ms'.format(options.benchmark, result)) | |
| if __name__ == '__main__': | |
| sys.exit(Main()) |