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)
This commit is contained in:
Pierre-Yves David 2014-10-09 22:57:52 -07:00
parent 372cc7c36d
commit 4e9488a8f8

View File

@ -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):