##// END OF EJS Templates
revsetbenchmarks: improve error output in case of failure...
revsetbenchmarks: improve error output in case of failure This helps with diagnostics.

File last commit:

r25529:3e80691d default
r25529:3e80691d default
Show More
revsetbenchmarks.py
156 lines | 4.4 KiB | text/x-python | PythonLexer
/ contrib / revsetbenchmarks.py
Pierre-Yves David
revsetbenchmark: simplify and convert the script to python...
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
Pierre-Yves David
revsetbenchmark: automatically finds the perf extension...
r21548 import os
Durham Goode
revsetbenchmark: remove python 2.7 dependency...
r20893 from subprocess import check_call, Popen, CalledProcessError, STDOUT, PIPE
Pierre-Yves David
revsetbenchmark: use optparse to retrieve argument...
r21287 # cannot use argparse, python 2.7 only
from optparse import OptionParser
Durham Goode
revsetbenchmark: remove python 2.7 dependency...
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:
Pierre-Yves David
revsetbenchmark: fix error raising...
r21202 raise CalledProcessError(proc.returncode, ' '.join(args[0]))
Durham Goode
revsetbenchmark: remove python 2.7 dependency...
r20893 return output
Pierre-Yves David
revsetbenchmark: simplify and convert the script to python...
r20848
Pierre-Yves David
revsetbenchmark: convert update to proper subprocess call
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
revsetbenchmarks: extract call to mercurial into a function...
r25528
def hg(cmd, repo=None):
"""run a mercurial command
<cmd> is the list of command + argument,
<repo> is an optional repository path to run this command in."""
fullcmd = ['./hg']
if repo is not None:
fullcmd += ['-R', repo]
fullcmd += ['--config',
'extensions.perf=' + os.path.join(contribdir, 'perf.py')]
fullcmd += cmd
return check_output(fullcmd, stderr=STDOUT)
Pierre-Yves David
revsetbenchmark: support for running on other repo...
r21549 def perf(revset, target=None):
Pierre-Yves David
revsetbenchmark: convert performance call to proper subprocess call
r20851 """run benchmark for this very revset"""
try:
Pierre-Yves David
revsetbenchmarks: extract call to mercurial into a function...
r25528 output = hg(['perfrevset', revset], repo=target)
Pierre-Yves David
revsetbenchmark: retrieve the benchmark value in python...
r20854 output = output.lstrip('!') # remove useless ! in this context
return output.strip()
Pierre-Yves David
revsetbenchmark: convert performance call to proper subprocess call
r20851 except CalledProcessError, exc:
Pierre-Yves David
revsetbenchmarks: improve error output in case of failure...
r25529 print >> sys.stderr, 'abort: cannot run revset benchmark: %s' % exc.cmd
if exc.output is None:
print >> sys.stderr, '(no ouput)'
else:
print >> sys.stderr, exc.output
Pierre-Yves David
revsetbenchmark: convert performance call to proper subprocess call
r20851 sys.exit(exc.returncode)
Pierre-Yves David
revsetbenchmark: convert revision display to proper subprocesscall
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
revsetbenchmark: get revision to benchmark in a function...
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
revsetbenchmark: use optparse to retrieve argument...
r21287 parser = OptionParser(usage="usage: %prog [options] <revs>")
parser.add_option("-f", "--file",
Mads Kiilerich
spelling: fixes from proofreading of spell checker issues
r23139 help="read revset from FILE (stdin if omitted)",
Pierre-Yves David
revsetbenchmark: make it clear that revsets may be read from stdin
r22555 metavar="FILE")
Pierre-Yves David
revsetbenchmark: support for running on other repo...
r21549 parser.add_option("-R", "--repo",
help="run benchmark on REPO", metavar="REPO")
Pierre-Yves David
revsetbenchmark: use optparse to retrieve argument...
r21287
(options, args) = parser.parse_args()
Pierre-Yves David
revsetbenchmark: simplify and convert the script to python...
r20848
Pierre-Yves David
revsetbenchmark: add a usage message when no arguments are passed...
r21286 if len(sys.argv) < 2:
Pierre-Yves David
revsetbenchmark: use optparse to retrieve argument...
r21287 parser.print_help()
Pierre-Yves David
revsetbenchmark: add a usage message when no arguments are passed...
r21286 sys.exit(255)
Pierre-Yves David
revsetbenchmark: automatically finds the perf extension...
r21548 # the directory where both this script and the perf.py extension live.
contribdir = os.path.dirname(__file__)
Pierre-Yves David
revsetbenchmark: use optparse to retrieve argument...
r21287
target_rev = args[0]
Pierre-Yves David
revsetbenchmark: simplify and convert the script to python...
r20848
revsetsfile = sys.stdin
Pierre-Yves David
revsetbenchmark: use optparse to retrieve argument...
r21287 if options.file:
revsetsfile = open(options.file)
Pierre-Yves David
revsetbenchmark: simplify and convert the script to python...
r20848
Pierre-Yves David
revsetbenchmark: allow comments ('#' prefix) in the revset input
r22556 revsets = [l.strip() for l in revsetsfile if not l.startswith('#')]
Pierre-Yves David
revsetbenchmark: simplify and convert the script to python...
r20848
print "Revsets to benchmark"
print "----------------------------"
for idx, rset in enumerate(revsets):
print "%i) %s" % (idx, rset)
print "----------------------------"
print
Pierre-Yves David
revsetbenchmark: get revision to benchmark in a function...
r20853 revs = getrevs(target_rev)
Pierre-Yves David
revsetbenchmark: simplify and convert the script to python...
r20848
Pierre-Yves David
revsetbenchmark: add a summary at the end of execution...
r20855 results = []
Pierre-Yves David
revsetbenchmark: simplify and convert the script to python...
r20848 for r in revs:
print "----------------------------"
Pierre-Yves David
revsetbenchmark: convert revision display to proper subprocesscall
r20852 printrevision(r)
Pierre-Yves David
revsetbenchmark: simplify and convert the script to python...
r20848 print "----------------------------"
Pierre-Yves David
revsetbenchmark: convert update to proper subprocess call
r20850 update(r)
Pierre-Yves David
revsetbenchmark: add a summary at the end of execution...
r20855 res = []
results.append(res)
Pierre-Yves David
revsetbenchmark: simplify and convert the script to python...
r20848 for idx, rset in enumerate(revsets):
Pierre-Yves David
revsetbenchmark: support for running on other repo...
r21549 data = perf(rset, target=options.repo)
Pierre-Yves David
revsetbenchmark: add a summary at the end of execution...
r20855 res.append(data)
print "%i)" % idx, data
sys.stdout.flush()
Pierre-Yves David
revsetbenchmark: simplify and convert the script to python...
r20848 print "----------------------------"
Pierre-Yves David
revsetbenchmark: add a summary at the end of execution...
r20855
print """
Result by revset
================
"""
print 'Revision:', revs
for idx, rev in enumerate(revs):
sys.stdout.write('%i) ' % idx)
sys.stdout.flush()
printrevision(rev)
print
print
for ridx, rset in enumerate(revsets):
print "revset #%i: %s" % (ridx, rset)
for idx, data in enumerate(results):
print '%i) %s' % (idx, data[ridx])
print