comparison mercurial/revset.py @ 21939:f486001f9d6f stable

revset: optimize baseset.__sub__ (issue4313) dd716807fd23 regressed performance of baseset.__sub__ by introducing a lazyset. This patch restores that lost performance by eagerly evaluating baseset.__sub__ if the other set is a baseset. revsetbenchmark.py results impacted by this change: revset #6: roots(0::tip) 0) wall 2.923473 comb 2.920000 user 2.920000 sys 0.000000 (best of 4) 1) wall 0.077614 comb 0.080000 user 0.080000 sys 0.000000 (best of 100) revset #23: roots((0:tip)::) 0) wall 2.875178 comb 2.880000 user 2.880000 sys 0.000000 (best of 4) 1) wall 0.154519 comb 0.150000 user 0.150000 sys 0.000000 (best of 61) On the author's machine, this slowdown manifested during evaluation of 'roots(%ln::)' in phases.retractboundary after unbundling the Firefox repository. Using `time hg unbundle firefox.hg` as a benchmark: Before: 8:00 After: 4:28 Delta: -3:32 For reference, the subset and cs baseset instances impacted by this change were of lengths 193634 and 193627, respectively. Explicit test coverage of roots(%ln::), while similar to the existing roots(0::tip) benchmark, has been added.
author Gregory Szorc <gregory.szorc@gmail.com>
date Thu, 24 Jul 2014 12:12:12 -0700
parents 7142e04b438e
children 3efe3c2609e0
comparison
equal deleted inserted replaced
21938:c8411fb5dfef 21939:f486001f9d6f
2230 2230
2231 def __sub__(self, other): 2231 def __sub__(self, other):
2232 """Returns a new object with the substraction of the two collections. 2232 """Returns a new object with the substraction of the two collections.
2233 2233
2234 This is part of the mandatory API for smartset.""" 2234 This is part of the mandatory API for smartset."""
2235 # If we are operating on 2 baseset, do the computation now since all
2236 # data is available. The alternative is to involve a lazyset, which
2237 # may be slow.
2238 if isinstance(other, baseset):
2239 other = other.set()
2240 return baseset([x for x in self if x not in other])
2241
2235 return self.filter(lambda x: x not in other) 2242 return self.filter(lambda x: x not in other)
2236 2243
2237 def __and__(self, other): 2244 def __and__(self, other):
2238 """Returns a new object with the intersection of the two collections. 2245 """Returns a new object with the intersection of the two collections.
2239 2246