[PATCH 1 of 7 Series-F] performance: speedup computation of obsolete revisions

pierre-yves.david at logilab.fr pierre-yves.david at logilab.fr
Tue Jan 8 12:54:00 CST 2013


# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at ens-lyon.org>
# Date 1357265694 -3600
# Node ID 191a394f3de541324eeb95c07426ebf9f3428aa7
# Parent  a32255dee8599db1e1fdcca1a4d09f0ed25b6d60
performance: speedup computation of obsolete revisions

In they current state revset call can be very costly as we test predicates on
the will repository. As obsolete computation is used by the "hidden" filter, it
needs to be very fast.

The current changeset drop revset call in favor of direct testing of the phase
of changeset.


Performance test on my Mercurial checkout

- 19857 total changesets,
- 1584 obsolete changesets,
- 13310 obsolescence markers.

Before this changes, :

  ! obsolete
  ! wall 0.047041 comb 0.050000 user 0.050000 sys 0.000000 (best of 100)
  ! hidden
  ! wall 0.115360 comb 0.110000 user 0.110000 sys 0.000000 (best of 84

After this changes:

  ! obsolete
  ! wall 0.004590 comb 0.010000 user 0.010000 sys 0.000000 (best of 599)
  ! hidden
  ! wall 0.071998 comb 0.070000 user 0.070000 sys 0.000000 (best of 100)


Performance test on a Mozilla central checkout:

- 117293 total changesets,
- 1 obsolete changeset,
- 1 obsolescence marker.

Before this changes, :

  ! obsolete
  ! wall 0.001539 comb 0.000000 user 0.000000 sys 0.000000 (best of 1524)
  ! hidden
  ! wall 0.364723 comb 0.360000 user 0.360000 sys 0.000000 (best of 27)

After this changes:

  ! obsolete
  ! wall 0.000017 comb 0.000000 user 0.000000 sys 0.000000 (best of 101306)
  ! hidden
  ! wall 0.367800 comb 0.360000 user 0.360000 sys 0.000000 (best of 27)

diff --git a/mercurial/obsolete.py b/mercurial/obsolete.py
--- a/mercurial/obsolete.py
+++ b/mercurial/obsolete.py
@@ -647,16 +647,17 @@ def clearobscaches(repo):
 
 @cachefor('obsolete')
 def _computeobsoleteset(repo):
     """the set of obsolete revisions"""
     obs = set()
-    nm = repo.changelog.nodemap
+    getrev = repo.changelog.nodemap.get
+    getphase = repo._phasecache.phase
     for node in repo.obsstore.successors:
-        rev = nm.get(node)
-        if rev is not None:
+        rev = getrev(node)
+        if rev is not None and getphase(repo, rev):
             obs.add(rev)
-    return set(repo.revs('%ld - public()', obs))
+    return obs
 
 @cachefor('unstable')
 def _computeunstableset(repo):
     """the set of non obsolete revisions with obsolete parents"""
     return set(repo.revs('(obsolete()::) - obsolete()'))


More information about the Mercurial-devel mailing list