D9023: branchmap: add a cache validation cache, avoid expensive re-hash on every use

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

D9023: branchmap: add a cache validation cache, avoid expensive re-hash on every use

marmoute (Pierre-Yves David)
spectral created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  In a pathological `hg log` case, we end up executing the branchmap validity
  checking twice per commit displayed. Or maybe we always do, and I just noticed
  because it's really slow in this repo for some reason.
 
  Before:
 
    Time (mean ± σ):      9.816 s ±  0.071 s    [User: 9.435 s, System: 0.392 s]
   
    Range (min … max):    9.709 s …  9.920 s
 
  After:
 
    Time (mean ± σ):      8.671 s ±  0.078 s    [User: 8.309 s, System: 0.392 s]
   
    Range (min … max):    8.594 s …  8.816 s

REPOSITORY
  rHG Mercurial

BRANCH
  default

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

AFFECTED FILES
  hg
  mercurial/changelog.py
  mercurial/scmutil.py

CHANGE DETAILS

diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -363,13 +363,15 @@
     cl = repo.changelog
     if not cl.filteredrevs:
         return None
-    key = None
-    revs = sorted(r for r in cl.filteredrevs if r <= maxrev)
-    if revs:
-        s = hashutil.sha1()
-        for rev in revs:
-            s.update(b'%d;' % rev)
-        key = s.digest()
+    key = cl._filteredrevs_hashcache.get(maxrev)
+    if not key:
+        revs = sorted(r for r in cl.filteredrevs if r <= maxrev)
+        if revs:
+            s = hashutil.sha1()
+            for rev in revs:
+                s.update(b'%d;' % rev)
+            key = s.digest()
+            cl._filteredrevs_hashcache[maxrev] = key
     return key
 
 
diff --git a/mercurial/changelog.py b/mercurial/changelog.py
--- a/mercurial/changelog.py
+++ b/mercurial/changelog.py
@@ -403,9 +403,21 @@
         self._delayed = False
         self._delaybuf = None
         self._divert = False
-        self.filteredrevs = frozenset()
+        self._filteredrevs = frozenset()
+        self._filteredrevs_hashcache = {}
         self._copiesstorage = opener.options.get(b'copies-storage')
 
+    @property
+    def filteredrevs(self):
+        return self._filteredrevs
+
+    @filteredrevs.setter
+    def filteredrevs(self, val):
+        # Ensure all updates go through this function
+        assert isinstance(val, frozenset)
+        self._filteredrevs = val
+        self._filteredrevs_hashcache = {}
+
     def delayupdate(self, tr):
         """delay visibility of index updates to other readers"""
 
diff --git a/hg b/hg
--- a/hg
+++ b/hg
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3.8
 #
 # mercurial - scalable distributed SCM
 #



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