js/src/devtools/gc/gc-test.py

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 # This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 # License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
michael@0 4
michael@0 5 # Works with python2.6
michael@0 6
michael@0 7 import datetime, os, re, sys, traceback
michael@0 8 import math, string, copy, json
michael@0 9 import subprocess
michael@0 10 from subprocess import *
michael@0 11 from operator import itemgetter
michael@0 12
michael@0 13 class Test:
michael@0 14 def __init__(self, path, name):
michael@0 15 self.path = path
michael@0 16 self.name = name
michael@0 17
michael@0 18 @classmethod
michael@0 19 def from_file(cls, path, name, options):
michael@0 20 return cls(path, name)
michael@0 21
michael@0 22 def find_tests(dir, substring = None):
michael@0 23 ans = []
michael@0 24 for dirpath, dirnames, filenames in os.walk(dir):
michael@0 25 if dirpath == '.':
michael@0 26 continue
michael@0 27 for filename in filenames:
michael@0 28 if not filename.endswith('.js'):
michael@0 29 continue
michael@0 30 test = os.path.join(dirpath, filename)
michael@0 31 if substring is None or substring in os.path.relpath(test, dir):
michael@0 32 ans.append([test, filename])
michael@0 33 return ans
michael@0 34
michael@0 35 def get_test_cmd(path):
michael@0 36 return [ JS, '-f', path ]
michael@0 37
michael@0 38 def avg(seq):
michael@0 39 return sum(seq) / len(seq)
michael@0 40
michael@0 41 def stddev(seq, mean):
michael@0 42 diffs = ((float(item) - mean) ** 2 for item in seq)
michael@0 43 return math.sqrt(sum(diffs) / len(seq))
michael@0 44
michael@0 45 def run_test(test):
michael@0 46 env = os.environ.copy()
michael@0 47 env['MOZ_GCTIMER'] = 'stderr'
michael@0 48 cmd = get_test_cmd(test.path)
michael@0 49 total = []
michael@0 50 mark = []
michael@0 51 sweep = []
michael@0 52 close_fds = sys.platform != 'win32'
michael@0 53 p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=close_fds, env=env)
michael@0 54 out, err = p.communicate()
michael@0 55 out, err = out.decode(), err.decode()
michael@0 56
michael@0 57 float_array = [float(_) for _ in err.split()]
michael@0 58
michael@0 59 if len(float_array) == 0:
michael@0 60 print('Error: No data from application. Configured with --enable-gctimer?')
michael@0 61 sys.exit(1)
michael@0 62
michael@0 63 for i, currItem in enumerate(float_array):
michael@0 64 if (i % 3 == 0):
michael@0 65 total.append(currItem)
michael@0 66 else:
michael@0 67 if (i % 3 == 1):
michael@0 68 mark.append(currItem)
michael@0 69 else:
michael@0 70 sweep.append(currItem)
michael@0 71
michael@0 72 return max(total), avg(total), max(mark), avg(mark), max(sweep), avg(sweep)
michael@0 73
michael@0 74 def run_tests(tests, test_dir):
michael@0 75 bench_map = {}
michael@0 76
michael@0 77 try:
michael@0 78 for i, test in enumerate(tests):
michael@0 79 filename_str = '"%s"' % test.name
michael@0 80 TMax, TAvg, MMax, MAvg, SMax, SAvg = run_test(test)
michael@0 81 bench_map[test.name] = [TMax, TAvg, MMax, MAvg, SMax, SAvg]
michael@0 82 fmt = '%20s: {"TMax": %4.1f, "TAvg": %4.1f, "MMax": %4.1f, "MAvg": %4.1f, "SMax": %4.1f, "SAvg": %4.1f}'
michael@0 83 if (i != len(tests) - 1):
michael@0 84 fmt += ','
michael@0 85 print(fmt %(filename_str ,TMax, TAvg, MMax, MAvg, SMax, MAvg))
michael@0 86 except KeyboardInterrupt:
michael@0 87 print('fail')
michael@0 88
michael@0 89 return dict((filename, dict(TMax=TMax, TAvg=TAvg, MMax=MMax, MAvg=MAvg, SMax=SMax, SAvg=SAvg))
michael@0 90 for filename, (TMax, TAvg, MMax, MAvg, SMax, SAvg) in bench_map.iteritems())
michael@0 91
michael@0 92 def compare(current, baseline):
michael@0 93 percent_speedups = []
michael@0 94 for key, current_result in current.iteritems():
michael@0 95 try:
michael@0 96 baseline_result = baseline[key]
michael@0 97 except KeyError:
michael@0 98 print key, 'missing from baseline'
michael@0 99 continue
michael@0 100
michael@0 101 val_getter = itemgetter('TMax', 'TAvg', 'MMax', 'MAvg', 'SMax', 'SAvg')
michael@0 102 BTMax, BTAvg, BMMax, BMAvg, BSMax, BSAvg = val_getter(baseline_result)
michael@0 103 CTMax, CTAvg, CMMax, CMAvg, CSMax, CSAvg = val_getter(current_result)
michael@0 104
michael@0 105 fmt = '%30s: %s'
michael@0 106 if CTAvg <= BTAvg:
michael@0 107 speedup = (CTAvg / BTAvg - 1) * 100
michael@0 108 result = 'faster: %6.2f < baseline %6.2f (%+6.2f%%)' % \
michael@0 109 (CTAvg, BTAvg, speedup)
michael@0 110 percent_speedups.append(speedup)
michael@0 111 else:
michael@0 112 slowdown = (CTAvg / BTAvg - 1) * 100
michael@0 113 result = 'SLOWER: %6.2f > baseline %6.2f (%+6.2f%%) ' % \
michael@0 114 (CTAvg, BTAvg, slowdown)
michael@0 115 percent_speedups.append(slowdown)
michael@0 116 print '%30s: %s' % (key, result)
michael@0 117 if percent_speedups:
michael@0 118 print 'Average speedup: %.2f%%' % avg(percent_speedups)
michael@0 119
michael@0 120 if __name__ == '__main__':
michael@0 121 script_path = os.path.abspath(__file__)
michael@0 122 script_dir = os.path.dirname(script_path)
michael@0 123 test_dir = os.path.join(script_dir, 'tests')
michael@0 124
michael@0 125 from optparse import OptionParser
michael@0 126 op = OptionParser(usage='%prog [options] JS_SHELL [TESTS]')
michael@0 127
michael@0 128 op.add_option('-b', '--baseline', metavar='JSON_PATH',
michael@0 129 dest='baseline_path', help='json file with baseline values to '
michael@0 130 'compare against')
michael@0 131
michael@0 132 (OPTIONS, args) = op.parse_args()
michael@0 133 if len(args) < 1:
michael@0 134 op.error('missing JS_SHELL argument')
michael@0 135 # We need to make sure we are using backslashes on Windows.
michael@0 136 JS, test_args = os.path.normpath(args[0]), args[1:]
michael@0 137
michael@0 138 test_list = []
michael@0 139 bench_map = {}
michael@0 140
michael@0 141 test_list = find_tests(test_dir)
michael@0 142
michael@0 143 if not test_list:
michael@0 144 print >> sys.stderr, "No tests found matching command line arguments."
michael@0 145 sys.exit(0)
michael@0 146
michael@0 147 test_list = [ Test.from_file(tst, name, OPTIONS) for tst, name in test_list ]
michael@0 148
michael@0 149 try:
michael@0 150 print("{")
michael@0 151 bench_map = run_tests(test_list, test_dir)
michael@0 152 print("}")
michael@0 153
michael@0 154 except OSError:
michael@0 155 if not os.path.exists(JS):
michael@0 156 print >> sys.stderr, "JS shell argument: file does not exist: '%s'"%JS
michael@0 157 sys.exit(1)
michael@0 158 else:
michael@0 159 raise
michael@0 160
michael@0 161 if OPTIONS.baseline_path:
michael@0 162 baseline_map = []
michael@0 163 fh = open(OPTIONS.baseline_path, 'r')
michael@0 164 baseline_map = json.load(fh)
michael@0 165 fh.close()
michael@0 166 compare(current=bench_map, baseline=baseline_map)

mercurial