blob: 7f139892c3aa2f39da0bf0a1c565875ddb35b135 [file] [log] [blame]
Rico Wind9d70f612018-08-31 09:17:43 +02001#!/usr/bin/env python
2# 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
6# Script for running kotlin based benchmarks
7
8import optparse
9import os
10import subprocess
11import sys
12import toolhelper
13import utils
14
15
16BENCHMARK_ROOT = os.path.join(utils.REPO_ROOT, 'third_party', 'benchmarks',
17 'kotlin-benches')
18
19BENCHMARK_PATTERN = '{benchmark}/kotlin/perf/build/libs/perf-1.0-BENCH.jar'
20BENCHMARK_MAIN_CLASS = 'com.android.kt.bms.cli.Runner'
21ART = os.path.join(utils.TOOLS_DIR, 'linux', 'art', 'bin', 'art')
22
23PROGUARD_CONF = """
24# From Android rules
25-keepclasseswithmembers public class * {
26 public static void main(java.lang.String[]);
27}
28# Disable obfuscation to only focus on shrinking
29-dontobfuscate
30# Once we're ready for optimization, we might want to relax access modifiers.
31-allowaccessmodification
32"""
33
34DEVICE_TEMP='/data/local/temp/bench'
35
36
37def parse_options():
38 result = optparse.OptionParser()
39 result.add_option('--api',
40 help='Android api level',
41 default='26',
42 choices=['21', '22', '23', '24', '25', '26'])
43 result.add_option('--benchmark',
44 help='The benchmark to run',
45 default='rgx',
46 choices=['rgx', 'deltablue', 'sta', 'empty'])
47 result.add_option('--no-build',
48 help='Don\'t build r8',
49 default=False, action='store_true')
50 result.add_option('--use-device',
51 help='Run the benchmark on an attaced device',
52 default=False, action='store_true')
53 return result.parse_args()
54
55
56def get_jar_for_benchmark(benchmark):
57 return os.path.join(BENCHMARK_ROOT,
58 BENCHMARK_PATTERN.format(benchmark=benchmark))
59
60def run_art(dex):
61 command = ['bash', ART, '-cp', dex, BENCHMARK_MAIN_CLASS]
62 utils.PrintCmd(command)
63 benchmark_output = subprocess.check_output(command)
64 return get_result(benchmark_output)
65
66def adb(args):
67 command = ['adb'] + args
68 utils.PrintCmd(command)
69 return subprocess.check_output(['adb'] + args)
70
71def get_result(output):
72 # There is a lot of debug output, with the actual results being in the line with:
73 # RESULTS,KtBench,KtBench,15719
74 # structure.
75 for result in [s for s in output.splitlines() if s.startswith('RESULTS')]:
76 return s.split('RESULTS,KtBench,KtBench,')[1]
77
78def run_art_device(dex):
79 adb(['wait-for-device', 'root'])
80 device_dst = os.path.join(DEVICE_TEMP, os.path.basename(dex))
81 adb(['push', dex, device_dst])
82 benchmark_output = adb(['shell', 'dalvikvm', '-cp', device_dst, BENCHMARK_MAIN_CLASS])
83 return get_result(benchmark_output)
84
85def Main():
86 (options, args) = parse_options()
87 temp = '/tmp/output'
88 dex_path = os.path.join(temp, "classes.jar")
89 proguard_conf = os.path.join(temp, 'proguard.conf')
90 with open(proguard_conf, 'w') as f:
91 f.write(PROGUARD_CONF)
92 benchmark_jar = get_jar_for_benchmark(options.benchmark)
93 r8_args = [
94 '--lib', utils.get_android_jar(26), # Only works with api 26
95 '--output', dex_path,
96 '--pg-conf', proguard_conf,
97 '--min-api', str(options.api),
98 benchmark_jar
99 ]
100 toolhelper.run('r8', r8_args, build=not options.no_build)
101 if options.use_device:
102 result = run_art_device(dex_path)
103 else:
104 result = run_art(dex_path)
105 print('Kotlin_{}(RunTimeRaw): {} ms'.format(options.benchmark, result))
106
107if __name__ == '__main__':
108 sys.exit(Main())