Patchwork [2,of,3] branchmap: issue a single call to `ancestors` for all heads

login
register
mail settings
Submitter Pierre-Yves David
Date Aug. 30, 2014, 3:02 p.m.
Message ID <bf342ea7ec283b44b0d3.1409410973@marginatus.alto.octopoid.net>
Download mbox | patch
Permalink /patch/5642/
State Accepted
Headers show

Comments

Pierre-Yves David - Aug. 30, 2014, 3:02 p.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david@fb.com>
# Date 1409394050 -7200
#      Sat Aug 30 12:20:50 2014 +0200
# Node ID bf342ea7ec283b44b0d382efd8869ab8f1caa125
# Parent  2946d2de8d59cc79e2746f6e93209367bb14310e
branchmap: issue a single call to `ancestors` for all heads

There are no reason to make multiple calls. This provides a massive speedup for
repo with a lot of heads.

On a strongly headed repo this gives humble speedup in simple case:

    from 8.1097 to 5.1051

And massive speedup in other case:

    from 7.8787 to 0.1984

Patch

diff --git a/mercurial/branchmap.py b/mercurial/branchmap.py
--- a/mercurial/branchmap.py
+++ b/mercurial/branchmap.py
@@ -250,19 +250,15 @@  class branchcache(dict):
             # run it again in case of doubt
             # assert not (set(bheadrevs) & set(newheadrevs))
             newheadrevs.sort()
             bheadset.update(newheadrevs)
 
-            # This loop prunes out two kinds of heads - heads that are
-            # superseded by a head in newheadrevs, and newheadrevs that are not
-            # heads because an existing head is their descendant.
-            while newheadrevs:
-                latest = newheadrevs.pop()
-                if latest not in bheadset:
-                    continue
-                ancestors = set(cl.ancestors([latest], min(bheadset)))
-                bheadset -= ancestors
+            # This prunes out two kinds of heads - heads that are superseded by
+            # a head in newheadrevs, and newheadrevs that are not heads because
+            # an existing head is their descendant.
+            ancestors = set(cl.ancestors(newheadrevs, min(bheadset)))
+            bheadset -= ancestors
             bheadrevs = sorted(bheadset)
             self[branch] = [cl.node(rev) for rev in bheadrevs]
             tiprev = bheadrevs[-1]
             if tiprev > self.tiprev:
                 self.tipnode = cl.node(tiprev)