blob: 3258d5365c1fda58403072a305be67d41d34fe40 [file] [log] [blame]
Peter Wen0cea52b2021-08-18 16:11:061#!/usr/bin/env python3
Avi Drissman73a09d12022-09-08 20:33:382# Copyright 2017 The Chromium Authors
bsheedy20e696b2017-09-13 20:31:053# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""Runs resource_sizes.py on two apks and outputs the diff."""
7
Raul Tambre9e24293b2019-05-12 06:11:078
bsheedy20e696b2017-09-13 20:31:059import argparse
10import json
bsheedy889406d2018-11-01 19:43:3411import logging
bsheedy20e696b2017-09-13 20:31:0512import os
13import subprocess
14import sys
15
16from pylib.constants import host_paths
bsheedy20e696b2017-09-13 20:31:0517
Haiyang Pan49830eb2024-06-27 20:25:4118with host_paths.SysPath(host_paths.BUILD_UTIL_PATH):
19 from lib.common import perf_tests_results_helper
bsheedy20e696b2017-09-13 20:31:0520
bsheedy889406d2018-11-01 19:43:3421with host_paths.SysPath(host_paths.TRACING_PATH):
22 from tracing.value import convert_chart_json # pylint: disable=import-error
23
bsheedy20e696b2017-09-13 20:31:0524_ANDROID_DIR = os.path.dirname(os.path.abspath(__file__))
Brian Sheedy45ea5b92019-04-16 17:37:4825with host_paths.SysPath(os.path.join(_ANDROID_DIR, 'gyp')):
26 from util import build_utils # pylint: disable=import-error
bsheedy20e696b2017-09-13 20:31:0527
28
29_BASE_CHART = {
30 'format_version': '0.1',
31 'benchmark_name': 'resource_sizes_diff',
32 'benchmark_description': 'APK resource size diff information',
33 'trace_rerun_options': [],
34 'charts': {},
35}
36
bsheedy889406d2018-11-01 19:43:3437_CHARTJSON_FILENAME = 'results-chart.json'
38_HISTOGRAMS_FILENAME = 'perf_results.json'
bsheedy20e696b2017-09-13 20:31:0539
40
41def DiffResults(chartjson, base_results, diff_results):
42 """Reports the diff between the two given results.
43
44 Args:
45 chartjson: A dictionary that chartjson results will be placed in, or None
46 to only print results.
47 base_results: The chartjson-formatted size results of the base APK.
48 diff_results: The chartjson-formatted size results of the diff APK.
49 """
Ben Joyced7822952021-08-17 17:19:0350 for graph_title, graph in base_results['charts'].items():
51 for trace_title, trace in graph.items():
bsheedy20e696b2017-09-13 20:31:0552 perf_tests_results_helper.ReportPerfResult(
53 chartjson, graph_title, trace_title,
54 diff_results['charts'][graph_title][trace_title]['value']
55 - trace['value'],
56 trace['units'], trace['improvement_direction'],
57 trace['important'])
58
59
60def AddIntermediateResults(chartjson, base_results, diff_results):
61 """Copies the intermediate size results into the output chartjson.
62
63 Args:
64 chartjson: A dictionary that chartjson results will be placed in.
65 base_results: The chartjson-formatted size results of the base APK.
66 diff_results: The chartjson-formatted size results of the diff APK.
67 """
Ben Joyced7822952021-08-17 17:19:0368 for graph_title, graph in base_results['charts'].items():
69 for trace_title, trace in graph.items():
bsheedy20e696b2017-09-13 20:31:0570 perf_tests_results_helper.ReportPerfResult(
71 chartjson, graph_title + '_base_apk', trace_title,
72 trace['value'], trace['units'], trace['improvement_direction'],
73 trace['important'])
74
75 # Both base_results and diff_results should have the same charts/traces, but
76 # loop over them separately in case they don't
Ben Joyced7822952021-08-17 17:19:0377 for graph_title, graph in diff_results['charts'].items():
78 for trace_title, trace in graph.items():
bsheedy20e696b2017-09-13 20:31:0579 perf_tests_results_helper.ReportPerfResult(
80 chartjson, graph_title + '_diff_apk', trace_title,
81 trace['value'], trace['units'], trace['improvement_direction'],
82 trace['important'])
83
84
85def _CreateArgparser():
bsheedy852269e2017-09-22 19:51:1086 def chromium_path(arg):
87 if arg.startswith('//'):
88 return os.path.join(host_paths.DIR_SOURCE_ROOT, arg[2:])
89 return arg
90
bsheedy20e696b2017-09-13 20:31:0591 argparser = argparse.ArgumentParser(
92 description='Diff resource sizes of two APKs. Arguments not listed here '
93 'will be passed on to both invocations of resource_sizes.py.')
94 argparser.add_argument('--chromium-output-directory-base',
95 dest='out_dir_base',
bsheedy852269e2017-09-22 19:51:1096 type=chromium_path,
bsheedy20e696b2017-09-13 20:31:0597 help='Location of the build artifacts for the base '
98 'APK, i.e. what the size increase/decrease will '
99 'be measured from.')
100 argparser.add_argument('--chromium-output-directory-diff',
101 dest='out_dir_diff',
bsheedy852269e2017-09-22 19:51:10102 type=chromium_path,
bsheedy20e696b2017-09-13 20:31:05103 help='Location of the build artifacts for the diff '
104 'APK.')
105 argparser.add_argument('--chartjson',
106 action='store_true',
bsheedy889406d2018-11-01 19:43:34107 help='DEPRECATED. Use --output-format=chartjson '
108 'instead.')
109 argparser.add_argument('--output-format',
110 choices=['chartjson', 'histograms'],
111 help='Output the results to a file in the given '
112 'format instead of printing the results.')
bsheedy20e696b2017-09-13 20:31:05113 argparser.add_argument('--include-intermediate-results',
114 action='store_true',
115 help='Include the results from the resource_sizes.py '
116 'runs in the chartjson output.')
117 argparser.add_argument('--output-dir',
118 default='.',
bsheedy852269e2017-09-22 19:51:10119 type=chromium_path,
bsheedy20e696b2017-09-13 20:31:05120 help='Directory to save chartjson to.')
121 argparser.add_argument('--base-apk',
122 required=True,
bsheedy852269e2017-09-22 19:51:10123 type=chromium_path,
bsheedy20e696b2017-09-13 20:31:05124 help='Path to the base APK, i.e. what the size '
125 'increase/decrease will be measured from.')
126 argparser.add_argument('--diff-apk',
127 required=True,
bsheedy852269e2017-09-22 19:51:10128 type=chromium_path,
bsheedy20e696b2017-09-13 20:31:05129 help='Path to the diff APK, i.e. the APK whose size '
130 'increase/decrease will be measured against the '
131 'base APK.')
132 return argparser
133
134
135def main():
136 args, unknown_args = _CreateArgparser().parse_known_args()
bsheedy889406d2018-11-01 19:43:34137 # TODO(bsheedy): Remove this once all uses of --chartjson are removed.
138 if args.chartjson:
139 args.output_format = 'chartjson'
140
141 chartjson = _BASE_CHART.copy() if args.output_format else None
bsheedy20e696b2017-09-13 20:31:05142
143 with build_utils.TempDir() as base_dir, build_utils.TempDir() as diff_dir:
144 # Run resource_sizes.py on the two APKs
145 resource_sizes_path = os.path.join(_ANDROID_DIR, 'resource_sizes.py')
bsheedy889406d2018-11-01 19:43:34146 shared_args = (['python', resource_sizes_path, '--output-format=chartjson']
bsheedy20e696b2017-09-13 20:31:05147 + unknown_args)
148
149 base_args = shared_args + ['--output-dir', base_dir, args.base_apk]
150 if args.out_dir_base:
151 base_args += ['--chromium-output-directory', args.out_dir_base]
bsheedya9d10792017-09-23 21:47:11152 try:
153 subprocess.check_output(base_args, stderr=subprocess.STDOUT)
154 except subprocess.CalledProcessError as e:
Raul Tambre9e24293b2019-05-12 06:11:07155 print(e.output)
bsheedya9d10792017-09-23 21:47:11156 raise
bsheedy20e696b2017-09-13 20:31:05157
158 diff_args = shared_args + ['--output-dir', diff_dir, args.diff_apk]
159 if args.out_dir_diff:
bsheedy135012ca2017-09-26 00:00:40160 diff_args += ['--chromium-output-directory', args.out_dir_diff]
bsheedya9d10792017-09-23 21:47:11161 try:
162 subprocess.check_output(diff_args, stderr=subprocess.STDOUT)
163 except subprocess.CalledProcessError as e:
Raul Tambre9e24293b2019-05-12 06:11:07164 print(e.output)
bsheedya9d10792017-09-23 21:47:11165 raise
bsheedy20e696b2017-09-13 20:31:05166
167 # Combine the separate results
Alexander Cooperf691b4dc2023-12-15 02:29:28168 with open(os.path.join(base_dir, _CHARTJSON_FILENAME)) as base_file:
169 base_results = json.load(base_file)
170 with open(os.path.join(diff_dir, _CHARTJSON_FILENAME)) as diff_file:
171 diff_results = json.load(diff_file)
bsheedy20e696b2017-09-13 20:31:05172 DiffResults(chartjson, base_results, diff_results)
173 if args.include_intermediate_results:
174 AddIntermediateResults(chartjson, base_results, diff_results)
175
bsheedy889406d2018-11-01 19:43:34176 if args.output_format:
177 chartjson_path = os.path.join(os.path.abspath(args.output_dir),
178 _CHARTJSON_FILENAME)
179 logging.critical('Dumping diff chartjson to %s', chartjson_path)
180 with open(chartjson_path, 'w') as outfile:
bsheedy20e696b2017-09-13 20:31:05181 json.dump(chartjson, outfile)
182
bsheedy889406d2018-11-01 19:43:34183 if args.output_format == 'histograms':
184 histogram_result = convert_chart_json.ConvertChartJson(chartjson_path)
185 if histogram_result.returncode != 0:
186 logging.error('chartjson conversion failed with error: %s',
187 histogram_result.stdout)
188 return 1
189
190 histogram_path = os.path.join(os.path.abspath(args.output_dir),
191 'perf_results.json')
192 logging.critical('Dumping diff histograms to %s', histogram_path)
193 with open(histogram_path, 'w') as json_file:
194 json_file.write(histogram_result.stdout)
Yoshisato Yanagisawa0f42f102021-11-30 14:04:37195 return 0
bsheedy889406d2018-11-01 19:43:34196
197
bsheedy20e696b2017-09-13 20:31:05198if __name__ == '__main__':
199 sys.exit(main())