[PATCH] largefiles: optimize status when files are specified (issue3144)

Na'Tosha Bard natosha at unity3d.com
Thu Dec 15 09:24:15 CST 2011


# HG changeset patch
# User Na'Tosha Bard <natosha at unity3d.com>
# Date 1323962606 -3600
# Node ID bcdc1c4a0b65ebf9134c988e6d8f10f7cdb0afa6
# Parent  e6868bd17f24324db347a289bb2ae0120dd5cd54
largefiles: optimize status when files are specified (issue3144)

This fixes a performance issue with 'hg status' when files are specified
on the command-line.  Previously, a large amount of largefiles code was
executed, even if files were specified on the command-line and those files
were not largefiles.  This patch fixes the problem by first checking if
non-largefiles were specified on the command-line and, just letting the
normal status function handle the case if they were.

On a brand new machine, the execution time for 'hg status filename' on
a repository with largefiles was:

real    0m0.636s
user    0m0.512s
sys     0m0.120s

versus the following (the same repository, with largefiles disabled):

real    0m0.215s
user    0m0.180s
sys     0m0.032s

After this patch, the performance of 'hg status filename' on the same
repository, with largefiles enabled is:

real    0m0.228s
user    0m0.189s
sys     0m0.036s

This performance boost is also true when patterns (rather than specific
files) are specified on the command-line.

In the case where patterns are specified in addition to a file list, we
just defer to the normal codepath in order to not spend extra time
expanding the patterns to just risk having to expand them again later.

diff -r e6868bd17f24 -r bcdc1c4a0b65 hgext/largefiles/reposetup.py
--- a/hgext/largefiles/reposetup.py	Fri Dec 09 17:58:12 2011 +0100
+++ b/hgext/largefiles/reposetup.py	Thu Dec 15 16:23:26 2011 +0100
@@ -113,6 +113,18 @@
                 if match is None:
                     match = match_.always(self.root, self.getcwd())
 
+                # First check if there were files specified on the
+                # command line.  If there were, and none of them were
+                # largefiles, we should just bail here and let super
+                # handle it -- thus gaining a big performance boost.
+                lfdirstate = lfutil.openlfdirstate(ui, self)
+                if match.files() and not match.anypats():
+                    matchedfiles = [f for f in match.files() if f in lfdirstate]
+                    if not matchedfiles:
+                        return super(lfiles_repo, self).status(node1, node2,
+                                match, listignored, listclean,
+                                listunknown, listsubrepos)
+
                 # Create a copy of match that matches standins instead
                 # of largefiles.
                 def tostandin(file):
@@ -144,7 +156,6 @@
                         # taken out or lfdirstate.status will report an error.
                         # The status of these files was already computed using
                         # super's status.
-                        lfdirstate = lfutil.openlfdirstate(ui, self)
                         # Override lfdirstate's ignore matcher to not do
                         # anything
                         orig_ignore = lfdirstate._ignore


More information about the Mercurial-devel mailing list