revsetbenchmarks.py
125 lines
| 3.5 KiB
| text/x-python
|
PythonLexer
/ contrib / revsetbenchmarks.py
Pierre-Yves David
|
r20848 | #!/usr/bin/env python | ||
# Measure the performance of a list of revsets against multiple revisions | ||||
# defined by parameter. Checkout one by one and run perfrevset with every | ||||
# revset in the list to benchmark its performance. | ||||
# | ||||
# - First argument is a revset of mercurial own repo to runs against. | ||||
# - Second argument is the file from which the revset array will be taken | ||||
# If second argument is omitted read it from standard input | ||||
# | ||||
# You should run this from the root of your mercurial repository. | ||||
# | ||||
# This script also does one run of the current version of mercurial installed | ||||
# to compare performance. | ||||
import sys | ||||
Durham Goode
|
r20893 | from subprocess import check_call, Popen, CalledProcessError, STDOUT, PIPE | ||
Pierre-Yves David
|
r20850 | |||
Durham Goode
|
r20893 | def check_output(*args, **kwargs): | ||
kwargs.setdefault('stderr', PIPE) | ||||
kwargs.setdefault('stdout', PIPE) | ||||
proc = Popen(*args, **kwargs) | ||||
output, error = proc.communicate() | ||||
if proc.returncode != 0: | ||||
raise CalledProcessError(proc.returncode, ' '.join(args)) | ||||
return output | ||||
Pierre-Yves David
|
r20848 | |||
Pierre-Yves David
|
r20850 | def update(rev): | ||
"""update the repo to a revision""" | ||||
try: | ||||
check_call(['hg', 'update', '--quiet', '--check', str(rev)]) | ||||
except CalledProcessError, exc: | ||||
print >> sys.stderr, 'update to revision %s failed, aborting' % rev | ||||
sys.exit(exc.returncode) | ||||
Pierre-Yves David
|
r20851 | def perf(revset): | ||
"""run benchmark for this very revset""" | ||||
try: | ||||
Pierre-Yves David
|
r20854 | output = check_output(['./hg', | ||
'--config', | ||||
'extensions.perf=contrib/perf.py', | ||||
'perfrevset', | ||||
revset], | ||||
stderr=STDOUT) | ||||
output = output.lstrip('!') # remove useless ! in this context | ||||
return output.strip() | ||||
Pierre-Yves David
|
r20851 | except CalledProcessError, exc: | ||
print >> sys.stderr, 'abort: cannot run revset benchmark' | ||||
sys.exit(exc.returncode) | ||||
Pierre-Yves David
|
r20852 | def printrevision(rev): | ||
"""print data about a revision""" | ||||
sys.stdout.write("Revision: ") | ||||
sys.stdout.flush() | ||||
check_call(['hg', 'log', '--rev', str(rev), '--template', | ||||
'{desc|firstline}\n']) | ||||
Pierre-Yves David
|
r20853 | def getrevs(spec): | ||
"""get the list of rev matched by a revset""" | ||||
try: | ||||
out = check_output(['hg', 'log', '--template={rev}\n', '--rev', spec]) | ||||
except CalledProcessError, exc: | ||||
print >> sys.stderr, "abort, can't get revision from %s" % spec | ||||
sys.exit(exc.returncode) | ||||
return [r for r in out.split() if r] | ||||
Pierre-Yves David
|
r20848 | |||
target_rev = sys.argv[1] | ||||
revsetsfile = sys.stdin | ||||
if len(sys.argv) > 2: | ||||
revsetsfile = open(sys.argv[2]) | ||||
revsets = [l.strip() for l in revsetsfile] | ||||
print "Revsets to benchmark" | ||||
print "----------------------------" | ||||
for idx, rset in enumerate(revsets): | ||||
print "%i) %s" % (idx, rset) | ||||
print "----------------------------" | ||||
Pierre-Yves David
|
r20853 | revs = getrevs(target_rev) | ||
Pierre-Yves David
|
r20848 | |||
Pierre-Yves David
|
r20855 | results = [] | ||
Pierre-Yves David
|
r20848 | for r in revs: | ||
print "----------------------------" | ||||
Pierre-Yves David
|
r20852 | printrevision(r) | ||
Pierre-Yves David
|
r20848 | print "----------------------------" | ||
Pierre-Yves David
|
r20850 | update(r) | ||
Pierre-Yves David
|
r20855 | res = [] | ||
results.append(res) | ||||
Pierre-Yves David
|
r20848 | for idx, rset in enumerate(revsets): | ||
Pierre-Yves David
|
r20855 | data = perf(rset) | ||
res.append(data) | ||||
print "%i)" % idx, data | ||||
sys.stdout.flush() | ||||
Pierre-Yves David
|
r20848 | print "----------------------------" | ||
Pierre-Yves David
|
r20855 | |||
print """ | ||||
Result by revset | ||||
================ | ||||
""" | ||||
print 'Revision:', revs | ||||
for idx, rev in enumerate(revs): | ||||
sys.stdout.write('%i) ' % idx) | ||||
sys.stdout.flush() | ||||
printrevision(rev) | ||||
for ridx, rset in enumerate(revsets): | ||||
print "revset #%i: %s" % (ridx, rset) | ||||
for idx, data in enumerate(results): | ||||
print '%i) %s' % (idx, data[ridx]) | ||||