spectral created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  The information calculated here was only needed if (a) --debug was specified, 
or
  (b) a directory move was plausibly detected. With tree manifests (especially 
in
  my pathological repo and with our custom setup), pre-calculating the `u1` and
  `u2` can be quite slow, and it's not even necessary in many cases. Let's delay
  calculating it until we know it's actually necessary. This should have no
  observable differences in output.
  
  Performance
  -----------
  
  I ran a rebase command in my pathological repo, rebasing two nodes across
  several public phase commits, but where no directory copies exist in any of 
the
  paths I'm tracking.
  
  Before
  ------
  
    Time (mean ± σ):      3.711 s ±  0.061 s    [User: 0.3 ms, System: 1.5 ms]
    Range (min … max):    3.640 s …  3.827 s    10 runs
  
  
  
  After
  -----
  
    Time (mean ± σ):     868.3 ms ±  10.1 ms    [User: 0.5 ms, System: 1.2 ms]
    Range (min … max):   856.6 ms … 883.6 ms    10 runs

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D9567

AFFECTED FILES
  mercurial/copies.py

CHANGE DETAILS

diff --git a/mercurial/copies.py b/mercurial/copies.py
--- a/mercurial/copies.py
+++ b/mercurial/copies.py
@@ -896,18 +896,30 @@
             )
 
     # find interesting file sets from manifests
-    addedinm1 = m1.filesnotin(mb, repo.narrowmatch())
-    addedinm2 = m2.filesnotin(mb, repo.narrowmatch())
-    u1 = sorted(addedinm1 - addedinm2)
-    u2 = sorted(addedinm2 - addedinm1)
+    cache = []
+    def _get_addedfiles(idx):
+        if not cache:
+            addedinm1 = m1.filesnotin(mb, repo.narrowmatch())
+            addedinm2 = m2.filesnotin(mb, repo.narrowmatch())
+            u1 = sorted(addedinm1 - addedinm2)
+            u2 = sorted(addedinm2 - addedinm1)
+            cache.extend((u1, u2))
+        return cache[idx]
 
-    header = b"  unmatched files in %s"
-    if u1:
-        repo.ui.debug(b"%s:\n   %s\n" % (header % b'local', b"\n   ".join(u1)))
-    if u2:
-        repo.ui.debug(b"%s:\n   %s\n" % (header % b'other', b"\n   ".join(u2)))
+    u1fn = lambda: _get_addedfiles(0)
+    u2fn = lambda: _get_addedfiles(1)
+    if repo.ui.debugflag:
+        u1 = u1fn()
+        u2 = u2fn()
 
-    if repo.ui.debugflag:
+        header = b"  unmatched files in %s"
+        if u1:
+            repo.ui.debug(b"%s:\n   %s\n" %
+                          (header % b'local', b"\n   ".join(u1)))
+        if u2:
+            repo.ui.debug(b"%s:\n   %s\n" %
+                          (header % b'other', b"\n   ".join(u2)))
+
         renamedeleteset = set()
         divergeset = set()
         for dsts in diverge.values():
@@ -941,8 +953,8 @@
 
     repo.ui.debug(b"  checking for directory renames\n")
 
-    dirmove1, movewithdir2 = _dir_renames(repo, c1, copy1, copies1, u2)
-    dirmove2, movewithdir1 = _dir_renames(repo, c2, copy2, copies2, u1)
+    dirmove1, movewithdir2 = _dir_renames(repo, c1, copy1, copies1, u2fn)
+    dirmove2, movewithdir1 = _dir_renames(repo, c2, copy2, copies2, u1fn)
 
     branch_copies1 = branch_copies(copy1, renamedelete1, dirmove1, 
movewithdir1)
     branch_copies2 = branch_copies(copy2, renamedelete2, dirmove2, 
movewithdir2)
@@ -950,14 +962,15 @@
     return branch_copies1, branch_copies2, diverge
 
 
-def _dir_renames(repo, ctx, copy, fullcopy, addedfiles):
+def _dir_renames(repo, ctx, copy, fullcopy, addedfilesfn):
     """Finds moved directories and files that should move with them.
 
     ctx: the context for one of the sides
     copy: files copied on the same side (as ctx)
     fullcopy: files copied on the same side (as ctx), including those that
               merge.manifestmerge() won't care about
-    addedfiles: added files on the other side (compared to ctx)
+    addedfilesfn: function returning added files on the other side (compared to
+                  ctx)
     """
     # generate a directory move map
     invalid = set()
@@ -997,7 +1010,7 @@
 
     movewithdir = {}
     # check unaccounted nonoverlapping files against directory moves
-    for f in addedfiles:
+    for f in addedfilesfn():
         if f not in fullcopy:
             for d in dirmove:
                 if f.startswith(d):



To: spectral, #hg-reviewers
Cc: mercurial-patches, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

Reply via email to