revset: make generatorset.__nonzero__ lazy
The 'for r in self:' call could trigger full consumption of the generator while
we only need a single value. We also fast path if a single value got already
computed. See inline comment for more details.
This provide massive speedup for lazy operation using boolean testing.
max(::tip)
e5b507efb36e) wall 0.055609 comb 0.060000 user 0.060000 sys 0.000000 (best of 100)
after change) wall 0.000109 comb 0.000000 user 0.000000 sys 0.000000 (best of 19146)
--- a/mercurial/revset.py Tue May 05 15:33:01 2015 -0700
+++ b/mercurial/revset.py Mon May 04 12:36:48 2015 -0700
@@ -3137,7 +3137,12 @@
self.__contains__ = self._desccontains
def __nonzero__(self):
- for r in self:
+ # Do not use 'for r in self' because it will enforce the iteration
+ # order (default ascending), possibly unrolling a whole descending
+ # iterator.
+ if self._genlist:
+ return True
+ for r in self._consumegen():
return True
return False