# HG changeset patch # User Durham Goode # Date 2014-10-28 21:06:06 # Node ID ac494b087febf0e00a84ff2a699c0690be2c453c # Parent 6df4bc39f6828e8aa74b33e51bc72eac621db2fe revset: fix O(2^n) perf regression in addset hg log -r 1 ... -r 100 was never returning due to a regression in the way addset computes __nonzero__. It used 'bool(self._r1 or self._r2)' which required executing self._r1.__nonzero__ twice (once for the or, once for the bool). hg log with a lot of -r's happens to build a one sided addset tree of N length, which ends up being 2^N performance. This patch fixes it by converting to bool before or'ing. This problem can be repro'd with something as simple as: hg log `for x in $(seq 1 50) ; do echo "-r $x "; done` Adding '1 + 2 + ... + 20' to the revsetbenchmark.txt didn't seem to repro the problem, so I wasn't able to add a revset benchmark for this issue. diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -2500,7 +2500,7 @@ class addset(abstractsmartset): return len(self._list) def __nonzero__(self): - return bool(self._r1 or self._r2) + return bool(self._r1) or bool(self._r2) @util.propertycache def _list(self):