aboutsummaryrefslogtreecommitdiff
path: root/compilation_stats.py
diff options
context:
space:
mode:
Diffstat (limited to 'compilation_stats.py')
-rwxr-xr-xcompilation_stats.py101
1 files changed, 101 insertions, 0 deletions
diff --git a/compilation_stats.py b/compilation_stats.py
new file mode 100755
index 0000000..78dea5f
--- /dev/null
+++ b/compilation_stats.py
@@ -0,0 +1,101 @@
+#! /usr/bin/env python3
+
+# Copyright (C) 2021 Linaro Limited. All rights received.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import argparse
+import os
+import sys
+import json
+import tempfile
+import shutil
+
+from collections import OrderedDict
+
+dir_benchs = os.path.dirname(os.path.realpath(__file__))
+dir_tools = os.path.join(dir_benchs, '..')
+sys.path.insert(0, dir_tools)
+
+from tools import utils, utils_adb, utils_print, utils_stats
+
+def BuildOptions():
+ parser = argparse.ArgumentParser(
+ description = "Collect compilation statistics.",
+ # Print default values.
+ formatter_class = argparse.ArgumentDefaultsHelpFormatter)
+ utils.AddCommonRunOptions(parser)
+ utils.AddOutputFormatOptions(parser, utils.default_output_formats)
+ args = parser.parse_args()
+ return args
+
+def SaveAndPrintResults(apk,
+ compilation_times,
+ section_sizes,
+ output_json_filename):
+ output_obj = utils.ReadJSON(output_json_filename)
+
+ apk_basename = os.path.basename(apk)
+ output_obj[apk_basename] = dict()
+
+ output_obj[apk_basename].update(compilation_times)
+ print("Compilation times (seconds):")
+ utils.PrintData(compilation_times)
+
+ output_obj[apk_basename]["Executable size"] = section_sizes
+ print("Executable sizes (bytes):")
+ utils.PrintData(section_sizes)
+
+ with open(output_json_filename, "w") as fp:
+ json.dump(output_obj, fp, indent=2)
+
+if __name__ == "__main__":
+ # create temp directory to pull executables from the device
+ # to measure their size
+ work_dir = tempfile.mkdtemp()
+ try:
+ args = BuildOptions()
+ apk = args.add_pathname[0]
+ apk_name = utils.TargetPathJoin(args.target_copy_path, apk)
+ # command is used to call a shell script using chroot
+ # this script calls dex2oat on a given APK and prints
+ # before/after timestamps
+ # after command is executed we pull the executable from the device
+ # and measure its size
+ if 'ART_COMMAND' in os.environ:
+ command = os.getenv('ART_COMMAND')
+ else:
+ utils.Error("ART_COMMAND is not set.")
+ format_data = {'workdir': os.path.dirname(apk_name)}
+ command = command.format(**format_data)
+
+ compilation_times = []
+ for i in range(args.iterations):
+ print("Compiling APK")
+ results = utils_adb.shell(command, args.target, exit_on_error=False)
+ lines = results[1]
+ compilation_time = utils.ExtractCompilationTimeFromOutput(lines)
+ compilation_times += [compilation_time]
+ print("Compilation took {:.2f}s\n".format(compilation_time))
+
+ # Pull the executable and get its size
+ local_oat = os.path.join(work_dir, apk + '.oat')
+ utils_adb.pull(args.output_oat, local_oat, args.target)
+ section_sizes = utils.GetSectionSizes(local_oat)
+
+ compile_time_dict = OrderedDict([("Time", compilation_times)])
+ SaveAndPrintResults(apk, compile_time_dict, section_sizes, args.output_json)
+
+ finally:
+ shutil.rmtree(work_dir)
+