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