# HG changeset patch # User Bryan O'Sullivan # Date 1334034986 25200 # Node ID 4df76d5506a9c09fed31715242bd6a4b5d808952 # Parent 79fecd735d267630ed860dda23ffb54cfbd12d88 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 79fecd735d26 -r 4df76d5506a9 mercurial/scmutil.py --- a/mercurial/scmutil.py Tue Apr 10 12:49:12 2012 -0500 +++ b/mercurial/scmutil.py Mon Apr 09 22:16:26 2012 -0700 @@ -534,6 +534,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: @@ -547,11 +549,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)