/js/src/metrics/gc/gc-test.py
http://github.com/zpao/v8monkey · Python · 178 lines · 146 code · 30 blank · 2 comment · 40 complexity · f5be5048a49175d8a69a83ddeb4fcfdc MD5 · raw file
- # Works with python2.6
- import datetime, os, re, sys, traceback
- import math, string, copy
- import subprocess
- from subprocess import *
- from operator import itemgetter
- 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}'
- 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)
- fmt = '%30s: %s'
- 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)
- def try_import_json():
- try:
- import json
- return json
- except ImportError:
- try:
- import simplejson as json
- return json
- except ImportError:
- pass
- 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 ]
- if OPTIONS.baseline_path:
- json = try_import_json()
- if not json:
- print('You need a json lib for baseline comparison')
- sys.exit(1)
- 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)