Mercurial > hg
changeset 19292:e0aa6fff8f02
annotate: simplify annotate parent function
The annotate algorithm used a custom parents() function to try to reuse
filectx and filelogs. I simplified it a bit to rely more heavily on the
self.parents() which makes it work well with alternative filectx
implementations. I tested performance on a file with 5000+ revisions
but no renames, and on a file with 500 revisions repeating a series of
4 edits+renames and saw zero performance hit. In fact, it was reliably a
couple milliseconds faster now.
Added the perfannotate command to contrib/perf.py for future use.
author | Durham Goode <durham@fb.com> |
---|---|
date | Thu, 30 May 2013 19:29:03 -0700 |
parents | 93635f69c93b |
children | 446ab88d3f1c |
files | contrib/perf.py mercurial/context.py |
diffstat | 2 files changed, 16 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/contrib/perf.py Thu May 30 19:26:56 2013 -0700 +++ b/contrib/perf.py Thu May 30 19:29:03 2013 -0700 @@ -45,6 +45,11 @@ except Exception: timer(lambda: len(list(cmdutil.walk(repo, pats, {})))) +@command('perfannotate') +def perfannotate(ui, repo, f): + fc = repo['.'][f] + timer(lambda: len(fc.annotate(True))) + @command('perfstatus', [('u', 'unknown', False, 'ask status to look for unknown files')])
--- a/mercurial/context.py Thu May 30 19:26:56 2013 -0700 +++ b/mercurial/context.py Thu May 30 19:29:03 2013 -0700 @@ -649,25 +649,21 @@ return child getlog = util.lrucachefunc(lambda x: self._repo.file(x)) - def getctx(path, fileid): - log = path == self._path and self._filelog or getlog(path) - return filectx(self._repo, path, fileid=fileid, filelog=log) - getctx = util.lrucachefunc(getctx) def parents(f): - # we want to reuse filectx objects as much as possible - p = f._path - if f._filerev is None: # working dir - pl = [(n.path(), n.filerev()) for n in f.parents()] - else: - pl = [(p, n) for n in f._filelog.parentrevs(f._filerev)] + pl = f.parents() + + # Don't return renamed parents if we aren't following. + if not follow: + pl = [p for p in pl if p.path() == f.path()] - if follow: - r = f.renamed() - if r: - pl[0] = (r[0], getlog(r[0]).rev(r[1])) + # renamed filectx won't have a filelog yet, so set it + # from the cache to save time + for p in pl: + if not '_filelog' in p.__dict__: + p._filelog = getlog(p.path()) - return [getctx(p, n) for p, n in pl if n != nullrev] + return pl # use linkrev to find the first changeset where self appeared if self.rev() != self.linkrev():