Mercurial > hg
changeset 25539:460922c95643
revsetbenchmarks: display relative change when meaningful
If the time difference is more than 5% from the previous run, we'll display
relative information. This makes it much simpler to spot performance changes in
a sea of benchmarks.
author | Pierre-Yves David <pierre-yves.david@fb.com> |
---|---|
date | Tue, 09 Jun 2015 21:30:04 -0700 |
parents | caff256205ea |
children | f08ad5d17e43 |
files | contrib/revsetbenchmarks.py |
diffstat | 1 files changed, 55 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/contrib/revsetbenchmarks.py Tue Jun 09 18:53:04 2015 -0700 +++ b/contrib/revsetbenchmarks.py Tue Jun 09 21:30:04 2015 -0700 @@ -11,6 +11,7 @@ import sys import os import re +import math from subprocess import check_call, Popen, CalledProcessError, STDOUT, PIPE # cannot use argparse, python 2.7 only from optparse import OptionParser @@ -103,10 +104,55 @@ idxwidth = 1 return idxwidth -def printresult(idx, data, maxidx, verbose=False): +def getfactor(main, other, field, sensitivity=0.05): + """return the relative factor between values for 'field' in main and other + + Return None if the factor is insignicant (less than <sensitivity> + variation).""" + factor = 1 + if main is not None: + factor = other[field] / main[field] + low, high = 1 - sensitivity, 1 + sensitivity + if (low < factor < high): + return None + return factor + +def formatfactor(factor): + """format a factor into a 4 char string + + 22% + 156% + x2.4 + x23 + x789 + x1e4 + x5x7 + + """ + if factor is None: + return ' ' + elif factor < 2: + return '%3i%%' % (factor * 100) + elif factor < 10: + return 'x%3.1f' % factor + elif factor < 1000: + return '%4s' % ('x%i' % factor) + else: + order = int(math.log(factor)) + 1 + while 1 < math.log(factor): + factor //= 0 + return 'x%ix%i' % (factor, order) + +_marker = object() +def printresult(idx, data, maxidx, verbose=False, reference=_marker): """print a line of result to stdout""" mask = '%%0%ii) %%s' % idxwidth(maxidx) out = ['%10.6f' % data['wall']] + if reference is not _marker: + factor = None + if reference is not None: + factor = getfactor(reference, data, 'wall') + out.append(formatfactor(factor)) if verbose: out.append('%10.6f' % data['comb']) out.append('%10.6f' % data['user']) @@ -114,9 +160,11 @@ out.append('%6d' % data['count']) print mask % (idx, ' '.join(out)) -def printheader(maxidx, verbose=False): +def printheader(maxidx, verbose=False, relative=False): header = [' ' * (idxwidth(maxidx) + 1), ' %-8s' % 'time'] + if relative: + header.append(' ') if verbose: header.append(' %-8s' % 'comb') header.append(' %-8s' % 'user') @@ -208,7 +256,10 @@ for ridx, rset in enumerate(revsets): print "revset #%i: %s" % (ridx, rset) - printheader(len(results), verbose=options.verbose) + printheader(len(results), verbose=options.verbose, relative=True) + ref = None for idx, data in enumerate(results): - printresult(idx, data[ridx], len(results), verbose=options.verbose) + printresult(idx, data[ridx], len(results), verbose=options.verbose, + reference=ref) + ref = data[ridx] print