[PATCH] revset: prefetch all attributes before loop in _revsbetween
Pierre-Yves David
pierre-yves.david at ens-lyon.org
Sat Jun 13 01:37:23 UTC 2015
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at fb.com>
# Date 1434048166 25200
# Thu Jun 11 11:42:46 2015 -0700
# Node ID 89b2644c6933cd28a83baf800c2fd3ab3530f468
# Parent 4388714b846e21cb2fefb686220c7c0d2df1b85a
revset: prefetch all attributes before loop in _revsbetween
Python is slow at attributes lookup. No, really, I mean -slow-. prefetching
these three methods give use a measurable performance boost.
revset #0: 0::tip
plain
0) 0.037655
1) 0.034290 91%
diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -89,27 +89,31 @@ def _revsbetween(repo, roots, heads):
seen = {}
# XXX this should be 'parentset.min()' assuming 'parentset' is a smartset
# (and if it is not, it should.)
minroot = min(roots)
roots = set(roots)
+ # prefetch all the things! (because python is slow)
+ reached = reachable.add
+ dovisit = visit.append
+ nextvisit = visit.pop
# open-code the post-order traversal due to the tiny size of
# sys.getrecursionlimit()
while visit:
- rev = visit.pop()
+ rev = nextvisit()
if rev in roots:
- reachable.add(rev)
+ reached(rev)
parents = parentrevs(rev)
seen[rev] = parents
for parent in parents:
if parent >= minroot and parent not in seen:
- visit.append(parent)
+ dovisit(parent)
if not reachable:
return baseset()
for rev in sorted(seen):
for parent in seen[rev]:
if parent in reachable:
- reachable.add(rev)
+ reached(rev)
return baseset(sorted(reachable))
elements = {
"(": (21, ("group", 1, ")"), ("func", 1, ")")),
"##": (20, None, ("_concat", 20)),
More information about the Mercurial-devel
mailing list