[PATCH STABLE] revset: fix O(2^n) perf regression in addset
Durham Goode
durham at fb.com
Tue Oct 28 21:20:27 UTC 2014
# HG changeset patch
# User Durham Goode <durham at fb.com>
# Date 1414530366 25200
# Tue Oct 28 14:06:06 2014 -0700
# Branch stable
# Node ID 247213e31a99056aa64b91d19592dcb72b436522
# 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):
More information about the Mercurial-devel
mailing list