revset: prefetch all attributes before loop in _revsbetween
authorPierre-Yves David <pierre-yves.david@fb.com>
Thu, 11 Jun 2015 11:42:46 -0700
changeset 25566 15412bba5a68
parent 25565 be4dc0007b8d
child 25567 f140d6207cca
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%
mercurial/revset.py
--- a/mercurial/revset.py	Thu Feb 07 00:32:26 2013 +0000
+++ b/mercurial/revset.py	Thu Jun 11 11:42:46 2015 -0700
@@ -91,23 +91,27 @@
     # (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 = {