diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /js/src/devtools/gc/gc-test.py | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/devtools/gc/gc-test.py')
-rw-r--r-- | js/src/devtools/gc/gc-test.py | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/js/src/devtools/gc/gc-test.py b/js/src/devtools/gc/gc-test.py new file mode 100644 index 0000000000..9b8fbc25b1 --- /dev/null +++ b/js/src/devtools/gc/gc-test.py @@ -0,0 +1,191 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Works with python2.6 + +import json +import math +import os +import sys +from operator import itemgetter +from subprocess import PIPE, Popen + + +class Test: + def __init__(self, path, name): + self.path = path + self.name = name + + @classmethod + def from_file(cls, path, name, options): + return cls(path, name) + + +def find_tests(dir, substring=None): + ans = [] + for dirpath, dirnames, filenames in os.walk(dir): + if dirpath == ".": + continue + for filename in filenames: + if not filename.endswith(".js"): + continue + test = os.path.join(dirpath, filename) + if substring is None or substring in os.path.relpath(test, dir): + ans.append([test, filename]) + return ans + + +def get_test_cmd(path): + return [JS, "-f", path] + + +def avg(seq): + return sum(seq) / len(seq) + + +def stddev(seq, mean): + diffs = ((float(item) - mean) ** 2 for item in seq) + return math.sqrt(sum(diffs) / len(seq)) + + +def run_test(test): + env = os.environ.copy() + env["MOZ_GCTIMER"] = "stderr" + cmd = get_test_cmd(test.path) + total = [] + mark = [] + sweep = [] + close_fds = sys.platform != "win32" + p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=close_fds, env=env) + out, err = p.communicate() + out, err = out.decode(), err.decode() + + float_array = [float(_) for _ in err.split()] + + if len(float_array) == 0: + print("Error: No data from application. Configured with --enable-gctimer?") + sys.exit(1) + + for i, currItem in enumerate(float_array): + if i % 3 == 0: + total.append(currItem) + else: + if i % 3 == 1: + mark.append(currItem) + else: + sweep.append(currItem) + + return max(total), avg(total), max(mark), avg(mark), max(sweep), avg(sweep) + + +def run_tests(tests, test_dir): + bench_map = {} + + try: + for i, test in enumerate(tests): + filename_str = '"%s"' % test.name + TMax, TAvg, MMax, MAvg, SMax, SAvg = run_test(test) + bench_map[test.name] = [TMax, TAvg, MMax, MAvg, SMax, SAvg] + fmt = '%20s: {"TMax": %4.1f, "TAvg": %4.1f, "MMax": %4.1f, "MAvg": %4.1f, "SMax": %4.1f, "SAvg": %4.1f}' # NOQA: E501 + if i != len(tests) - 1: + fmt += "," + print(fmt % (filename_str, TMax, TAvg, MMax, MAvg, SMax, MAvg)) + except KeyboardInterrupt: + print("fail") + + return dict( + ( + filename, + dict(TMax=TMax, TAvg=TAvg, MMax=MMax, MAvg=MAvg, SMax=SMax, SAvg=SAvg), + ) + for filename, (TMax, TAvg, MMax, MAvg, SMax, SAvg) in bench_map.iteritems() + ) + + +def compare(current, baseline): + percent_speedups = [] + for key, current_result in current.iteritems(): + try: + baseline_result = baseline[key] + except KeyError: + print(key, "missing from baseline") + continue + + val_getter = itemgetter("TMax", "TAvg", "MMax", "MAvg", "SMax", "SAvg") + BTMax, BTAvg, BMMax, BMAvg, BSMax, BSAvg = val_getter(baseline_result) + CTMax, CTAvg, CMMax, CMAvg, CSMax, CSAvg = val_getter(current_result) + + if CTAvg <= BTAvg: + speedup = (CTAvg / BTAvg - 1) * 100 + result = "faster: %6.2f < baseline %6.2f (%+6.2f%%)" % ( + CTAvg, + BTAvg, + speedup, + ) + percent_speedups.append(speedup) + else: + slowdown = (CTAvg / BTAvg - 1) * 100 + result = "SLOWER: %6.2f > baseline %6.2f (%+6.2f%%) " % ( + CTAvg, + BTAvg, + slowdown, + ) + percent_speedups.append(slowdown) + print("%30s: %s" % (key, result)) + if percent_speedups: + print("Average speedup: %.2f%%" % avg(percent_speedups)) + + +if __name__ == "__main__": + script_path = os.path.abspath(__file__) + script_dir = os.path.dirname(script_path) + test_dir = os.path.join(script_dir, "tests") + + from optparse import OptionParser + + op = OptionParser(usage="%prog [options] JS_SHELL [TESTS]") + + op.add_option( + "-b", + "--baseline", + metavar="JSON_PATH", + dest="baseline_path", + help="json file with baseline values to " "compare against", + ) + + (OPTIONS, args) = op.parse_args() + if len(args) < 1: + op.error("missing JS_SHELL argument") + # We need to make sure we are using backslashes on Windows. + JS, test_args = os.path.normpath(args[0]), args[1:] + + test_list = [] + bench_map = {} + + test_list = find_tests(test_dir) + + if not test_list: + print >>sys.stderr, "No tests found matching command line arguments." + sys.exit(0) + + test_list = [Test.from_file(tst, name, OPTIONS) for tst, name in test_list] + + try: + print("{") + bench_map = run_tests(test_list, test_dir) + print("}") + + except OSError: + if not os.path.exists(JS): + print >>sys.stderr, "JS shell argument: file does not exist: '%s'" % JS + sys.exit(1) + else: + raise + + if OPTIONS.baseline_path: + baseline_map = [] + fh = open(OPTIONS.baseline_path, "r") + baseline_map = json.load(fh) + fh.close() + compare(current=bench_map, baseline=baseline_map) |