[PATCH] revset: don't create changectx when matching for files

Durham Goode durham at fb.com
Tue Mar 17 16:57:12 UTC 2015


# HG changeset patch
# User Durham Goode <durham at fb.com>
# Date 1426610443 25200
#      Tue Mar 17 09:40:43 2015 -0700
# Node ID 5d4d0a97ccd85132bb5b1a640543cd24350b36c8
# Parent  567ae53657544744155897ada91f16f8af61ad8a
revset: don't create changectx when matching for files

When running 'hg log some/dir/' on a large repo about 25% of the time was spent
just creating changectxs to call ctx.files() on. Let's just skip that part.

On a large repo, running 'hg log some/path/ -l 200' went from 12s to 8.8s (27%
better) while traversing 90,000 commits.

diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -1070,8 +1070,13 @@ def _matchfiles(repo, subset, x):
     m = matchmod.match(repo.root, repo.getcwd(), pats, include=inc,
                        exclude=exc, ctx=repo[rev], default=default)
 
+    changelog = repo.changelog
     def matches(x):
-        for f in repo[x].files():
+        # Creating a ctx and calling ctx.files() is expensive when iterating
+        # over every commit in the changelog. We can save 30% or so by avoiding
+        # the ctx creation.
+        c = changelog.read(x)
+        for f in c[3]:
             if m(f):
                 return True
         return False


More information about the Mercurial-devel mailing list