diff options
Diffstat (limited to 'contrib/perf.py')
-rw-r--r-- | contrib/perf.py | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/contrib/perf.py b/contrib/perf.py new file mode 100644 index 0000000..574e899 --- /dev/null +++ b/contrib/perf.py @@ -0,0 +1,252 @@ +# perf.py - performance test routines +'''helper extension to measure performance''' + +from mercurial import cmdutil, scmutil, util, match, commands +import time, os, sys + +def timer(func, title=None): + results = [] + begin = time.time() + count = 0 + while True: + ostart = os.times() + cstart = time.time() + r = func() + cstop = time.time() + ostop = os.times() + count += 1 + a, b = ostart, ostop + results.append((cstop - cstart, b[0] - a[0], b[1]-a[1])) + if cstop - begin > 3 and count >= 100: + break + if cstop - begin > 10 and count >= 3: + break + if title: + sys.stderr.write("! %s\n" % title) + if r: + sys.stderr.write("! result: %s\n" % r) + m = min(results) + sys.stderr.write("! wall %f comb %f user %f sys %f (best of %d)\n" + % (m[0], m[1] + m[2], m[1], m[2], count)) + +def perfwalk(ui, repo, *pats): + try: + m = scmutil.match(repo[None], pats, {}) + timer(lambda: len(list(repo.dirstate.walk(m, [], True, False)))) + except Exception: + try: + m = scmutil.match(repo[None], pats, {}) + timer(lambda: len([b for a, b, c in repo.dirstate.statwalk([], m)])) + except Exception: + timer(lambda: len(list(cmdutil.walk(repo, pats, {})))) + +def perfstatus(ui, repo, *pats): + #m = match.always(repo.root, repo.getcwd()) + #timer(lambda: sum(map(len, repo.dirstate.status(m, [], False, False, + # False)))) + timer(lambda: sum(map(len, repo.status()))) + +def clearcaches(cl): + # behave somewhat consistently across internal API changes + if util.safehasattr(cl, 'clearcaches'): + cl.clearcaches() + elif util.safehasattr(cl, '_nodecache'): + from mercurial.node import nullid, nullrev + cl._nodecache = {nullid: nullrev} + cl._nodepos = None + +def perfheads(ui, repo): + cl = repo.changelog + def d(): + len(cl.headrevs()) + clearcaches(cl) + timer(d) + +def perftags(ui, repo): + import mercurial.changelog, mercurial.manifest + def t(): + repo.changelog = mercurial.changelog.changelog(repo.sopener) + repo.manifest = mercurial.manifest.manifest(repo.sopener) + repo._tags = None + return len(repo.tags()) + timer(t) + +def perfancestors(ui, repo): + heads = repo.changelog.headrevs() + def d(): + for a in repo.changelog.ancestors(heads): + pass + timer(d) + +def perfdirstate(ui, repo): + "a" in repo.dirstate + def d(): + repo.dirstate.invalidate() + "a" in repo.dirstate + timer(d) + +def perfdirstatedirs(ui, repo): + "a" in repo.dirstate + def d(): + "a" in repo.dirstate._dirs + del repo.dirstate._dirs + timer(d) + +def perfdirstatewrite(ui, repo): + ds = repo.dirstate + "a" in ds + def d(): + ds._dirty = True + ds.write() + timer(d) + +def perfmanifest(ui, repo): + def d(): + t = repo.manifest.tip() + m = repo.manifest.read(t) + repo.manifest.mapcache = None + repo.manifest._cache = None + timer(d) + +def perfchangeset(ui, repo, rev): + n = repo[rev].node() + def d(): + c = repo.changelog.read(n) + #repo.changelog._cache = None + timer(d) + +def perfindex(ui, repo): + import mercurial.revlog + mercurial.revlog._prereadsize = 2**24 # disable lazy parser in old hg + n = repo["tip"].node() + def d(): + cl = mercurial.revlog.revlog(repo.sopener, "00changelog.i") + cl.rev(n) + timer(d) + +def perfstartup(ui, repo): + cmd = sys.argv[0] + def d(): + os.system("HGRCPATH= %s version -q > /dev/null" % cmd) + timer(d) + +def perfparents(ui, repo): + nl = [repo.changelog.node(i) for i in xrange(1000)] + def d(): + for n in nl: + repo.changelog.parents(n) + timer(d) + +def perflookup(ui, repo, rev): + timer(lambda: len(repo.lookup(rev))) + +def perfrevrange(ui, repo, *specs): + revrange = scmutil.revrange + timer(lambda: len(revrange(repo, specs))) + +def perfnodelookup(ui, repo, rev): + import mercurial.revlog + mercurial.revlog._prereadsize = 2**24 # disable lazy parser in old hg + n = repo[rev].node() + def d(): + cl = mercurial.revlog.revlog(repo.sopener, "00changelog.i") + cl.rev(n) + timer(d) + +def perfnodelookup(ui, repo, rev): + import mercurial.revlog + mercurial.revlog._prereadsize = 2**24 # disable lazy parser in old hg + n = repo[rev].node() + cl = mercurial.revlog.revlog(repo.sopener, "00changelog.i") + def d(): + cl.rev(n) + clearcaches(cl) + timer(d) + +def perflog(ui, repo, **opts): + ui.pushbuffer() + timer(lambda: commands.log(ui, repo, rev=[], date='', user='', + copies=opts.get('rename'))) + ui.popbuffer() + +def perftemplating(ui, repo): + ui.pushbuffer() + timer(lambda: commands.log(ui, repo, rev=[], date='', user='', + template='{date|shortdate} [{rev}:{node|short}]' + ' {author|person}: {desc|firstline}\n')) + ui.popbuffer() + +def perfcca(ui, repo): + timer(lambda: scmutil.casecollisionauditor(ui, False, repo.dirstate)) + +def perffncacheload(ui, repo): + from mercurial import scmutil, store + s = store.store(set(['store','fncache']), repo.path, scmutil.opener) + def d(): + s.fncache._load() + timer(d) + +def perffncachewrite(ui, repo): + from mercurial import scmutil, store + s = store.store(set(['store','fncache']), repo.path, scmutil.opener) + s.fncache._load() + def d(): + s.fncache._dirty = True + s.fncache.write() + timer(d) + +def perfdiffwd(ui, repo): + """Profile diff of working directory changes""" + options = { + 'w': 'ignore_all_space', + 'b': 'ignore_space_change', + 'B': 'ignore_blank_lines', + } + + for diffopt in ('', 'w', 'b', 'B', 'wB'): + opts = dict((options[c], '1') for c in diffopt) + def d(): + ui.pushbuffer() + commands.diff(ui, repo, **opts) + ui.popbuffer() + title = 'diffopts: %s' % (diffopt and ('-' + diffopt) or 'none') + timer(d, title) + +def perfrevlog(ui, repo, file_, **opts): + from mercurial import revlog + dist = opts['dist'] + def d(): + r = revlog.revlog(lambda fn: open(fn, 'rb'), file_) + for x in xrange(0, len(r), dist): + r.revision(r.node(x)) + + timer(d) + +cmdtable = { + 'perfcca': (perfcca, []), + 'perffncacheload': (perffncacheload, []), + 'perffncachewrite': (perffncachewrite, []), + 'perflookup': (perflookup, []), + 'perfrevrange': (perfrevrange, []), + 'perfnodelookup': (perfnodelookup, []), + 'perfparents': (perfparents, []), + 'perfstartup': (perfstartup, []), + 'perfstatus': (perfstatus, []), + 'perfwalk': (perfwalk, []), + 'perfmanifest': (perfmanifest, []), + 'perfchangeset': (perfchangeset, []), + 'perfindex': (perfindex, []), + 'perfheads': (perfheads, []), + 'perftags': (perftags, []), + 'perfancestors': (perfancestors, []), + 'perfdirstate': (perfdirstate, []), + 'perfdirstatedirs': (perfdirstate, []), + 'perfdirstatewrite': (perfdirstatewrite, []), + 'perflog': (perflog, + [('', 'rename', False, 'ask log to follow renames')]), + 'perftemplating': (perftemplating, []), + 'perfdiffwd': (perfdiffwd, []), + 'perfrevlog': (perfrevlog, + [('d', 'dist', 100, 'distance between the revisions')], + "[INDEXFILE]"), +} |