revset: cache most conditions used in `filter`
authorPierre-Yves David <pierre-yves.david@fb.com>
Thu, 09 Oct 2014 22:57:52 -0700
changeset 22864 96b6b3d78697
parent 22863 a1a02b516cca
child 22865 09951bedbf35
revset: cache most conditions used in `filter` Except when stated otherwise, the condition used in `smartset.filter` will be cached. A new argument has been introduced to disable that behavior. We use it for filters created from `and` and `sub` operations. This gives massive performance boosts for revsets with expensive conditions. revset: branch(stable) or branch(default) before) wall 4.329070 comb 4.320000 user 4.310000 sys 0.010000 (best of 3) after) wall 2.356451 comb 2.360000 user 2.330000 sys 0.030000 (best of 4) revset: author(mpm) or author(lmoscovicz) before) wall 4.434719 comb 4.440000 user 4.440000 sys 0.000000 (best of 3) after) wall 2.321720 comb 2.320000 user 2.320000 sys 0.000000 (best of 4)
mercurial/revset.py
--- a/mercurial/revset.py	Thu Oct 09 04:12:20 2014 -0700
+++ b/mercurial/revset.py	Thu Oct 09 22:57:52 2014 -0700
@@ -2277,7 +2277,7 @@
         """Returns a new object with the intersection of the two collections.
 
         This is part of the mandatory API for smartset."""
-        return self.filter(other.__contains__)
+        return self.filter(other.__contains__, cache=False)
 
     def __add__(self, other):
         """Returns a new object with the union of the two collections.
@@ -2290,15 +2290,18 @@
 
         This is part of the mandatory API for smartset."""
         c = other.__contains__
-        return self.filter(lambda r: not c(r))
-
-    def filter(self, condition):
+        return self.filter(lambda r: not c(r), cache=False)
+
+    def filter(self, condition, cache=True):
         """Returns this smartset filtered by condition as a new smartset.
 
         `condition` is a callable which takes a revision number and returns a
         boolean.
 
         This is part of the mandatory API for smartset."""
+        # builtin cannot be cached. but do not needs to
+        if cache and util.safehasattr(condition, 'func_code'):
+            condition = util.cachefunc(condition)
         return filteredset(self, condition)
 
 class baseset(abstractsmartset):