[PATCH fix] scmutil: speed up revrange
Bryan O'Sullivan
bos at serpentine.com
Tue Apr 10 00:16:44 CDT 2012
# HG changeset patch
# User Bryan O'Sullivan <bryano at fb.com>
# Date 1334034986 25200
# Node ID a7c95cce790c1b08d06eb9bf0cc4fc641e97fc6b
# Parent 335f75e60efcd8a885a03692443785bb8eba9ad3
scmutil: speed up revrange
This improves the performance of "hg log -l1" from 0.21 seconds to
0.07 on a Linux kernel tree.
Ideally we could use xrange instead of range on the most common
path, and thus avoid a ton of allocation, but xrange doesn't support
slice-based indexing.
diff -r 335f75e60efc -r a7c95cce790c mercurial/scmutil.py
--- a/mercurial/scmutil.py Mon Apr 09 17:22:45 2012 -0700
+++ b/mercurial/scmutil.py Mon Apr 09 22:16:26 2012 -0700
@@ -527,6 +527,8 @@
seen, l = set(), []
for spec in revs:
+ if l and not seen:
+ seen = set(l)
# attempt to parse old-style ranges first to deal with
# things like old-tag which contain query metacharacters
try:
@@ -540,11 +542,18 @@
start = revfix(repo, start, 0)
end = revfix(repo, end, len(repo) - 1)
step = start > end and -1 or 1
- for rev in xrange(start, end + step, step):
- if rev in seen:
- continue
- seen.add(rev)
- l.append(rev)
+ if not seen and not l:
+ # by far the most common case: revs = ["-1:0"]
+ l = range(start, end + step, step)
+ # defer syncing seen until next iteration
+ continue
+ newrevs = set(xrange(start, end + step, step))
+ if seen:
+ newrevs.difference_update(seen)
+ seen.union(newrevs)
+ else:
+ seen = newrevs
+ l.extend(sorted(newrevs, reverse=start > end))
continue
elif spec and spec in repo: # single unquoted rev
rev = revfix(repo, spec, None)
More information about the Mercurial-devel
mailing list