[PATCH 3 of 4] revset-ancestors: use and iterator instead of a dequeu
Pierre-Yves David
pierre-yves.david at ens-lyon.org
Mon May 4 17:25:54 CDT 2015
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at fb.com>
# Date 1395876090 25200
# Wed Mar 26 16:21:30 2014 -0700
# Node ID dffaf3d15f9587d3f4e00a03cd288108c5cc78fe
# Parent 8aff772b686be3240fc04dc633dff18299ba7151
revset-ancestors: use and iterator instead of a dequeu
The dequeue was actually just used to be able to pop value one at a time.
Building the dequeue mean we are reading all the input value at once at the
beginning of the evaluation. This defeat the lazyness of revset.
We replace the deque with iterator usage for the sake of simplicity and
lazyness.
This provide massive speedup to get the first result if the input set is big
max(::all())
before) wall 0.001917 comb 0.000000 user 0.000000 sys 0.000000 (best of 1115)
after) wall 0.000107 comb 0.000000 user 0.000000 sys 0.000000 (best of 22222)
diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -23,27 +23,30 @@ def _revancestors(repo, revs, followfirs
else:
cut = None
cl = repo.changelog
def iterate():
- revqueue, inputrev = None, None
h = []
revs.sort(reverse=True)
- revqueue = util.deque(revs)
- if revqueue:
- inputrev = revqueue.popleft()
+ irevs = iter(revs)
+ try:
+ inputrev = irevs.next()
heapq.heappush(h, -inputrev)
+ except StopIteration:
+ irevs, inputrev = None, None
seen = set()
while h:
current = -heapq.heappop(h)
if current not in seen:
- if inputrev and current == inputrev:
- if revqueue:
- inputrev = revqueue.popleft()
+ if irevs is not None and current == inputrev:
+ try:
+ inputrev = irevs.next()
heapq.heappush(h, -inputrev)
+ except StopIteration:
+ irevs, inputrev = None, None
seen.add(current)
yield current
for parent in cl.parentrevs(current)[:cut]:
if parent != node.nullrev:
heapq.heappush(h, -parent)
More information about the Mercurial-devel
mailing list