From 4e9488a8f824532d139776118f6bcea9d93a53ce Mon Sep 17 00:00:00 2001 From: Pierre-Yves David Date: Thu, 9 Oct 2014 22:57:52 -0700 Subject: [PATCH] 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 | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/mercurial/revset.py b/mercurial/revset.py index 24349523ac..b80d66b98e 100644 --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -2277,7 +2277,7 @@ class abstractsmartset(object): """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 @@ class abstractsmartset(object): This is part of the mandatory API for smartset.""" c = other.__contains__ - return self.filter(lambda r: not c(r)) + return self.filter(lambda r: not c(r), cache=False) - def filter(self, condition): + 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):