[PATCH] revlog: optimize ancestors() to not check filtered revisions for each
Yuya Nishihara
yuya at tcha.org
Fri Oct 12 05:22:12 UTC 2018
# HG changeset patch
# User Yuya Nishihara <yuya at tcha.org>
# Date 1539318163 -7200
# Fri Oct 12 06:22:43 2018 +0200
# Node ID 7bbc8f3037c847d44447d0088610451a80f0aaeb
# Parent 74558635dad53eccbbe2e67df835df0873d5c870
revlog: optimize ancestors() to not check filtered revisions for each
While reviewing the Rust implementation, I noticed iter(ancestors) doesn't
need to check filtering state for each parent revision. And doing that appears
to have some measurable perf win.
$ hg perfancestors -R mercurial
(orig) wall 0.038093 comb 0.040000 user 0.040000 sys 0.000000 (best of 100)
(this) wall 0.024795 comb 0.020000 user 0.020000 sys 0.000000 (best of 117)
diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -648,6 +648,9 @@ class revlog(object):
return entry[5], entry[6]
+ # fast parentrevs(rev) where rev isn't filtered
+ _uncheckedparentrevs = parentrevs
+
def node(self, rev):
try:
return self.index[rev][7]
@@ -747,8 +750,14 @@ class revlog(object):
See the documentation for ancestor.lazyancestors for more details."""
- return ancestor.lazyancestors(self.parentrevs, revs, stoprev=stoprev,
- inclusive=inclusive)
+ # first, make sure start revisions aren't filtered
+ revs = list(revs)
+ checkrev = self.node
+ for r in revs:
+ checkrev(r)
+ # and we're sure ancestors aren't filtered as well
+ return ancestor.lazyancestors(self._uncheckedparentrevs, revs,
+ stoprev=stoprev, inclusive=inclusive)
def descendants(self, revs):
return dagop.descendantrevs(revs, self.revs, self.parentrevs)
More information about the Mercurial-devel
mailing list