Patchwork [2,of,2,V2] revset: speed up existence checks for ordered filtered sets

login
register
mail settings
Submitter Durham Goode
Date Sept. 22, 2015, 2:17 a.m.
Message ID <9253d937b57d48c693c2.1442888274@dev2000.prn2.facebook.com>
Download mbox | patch
Permalink /patch/10563/
State Accepted
Headers show

Comments

Durham Goode - Sept. 22, 2015, 2:17 a.m.
# HG changeset patch
# User Durham Goode <durham@fb.com>
# Date 1442793222 25200
#      Sun Sep 20 16:53:42 2015 -0700
# Node ID 9253d937b57d48c693c2820d914683efd2dfc00c
# Parent  ab2a19c6961805bc67b0db2d615dc3fdfa949cb8
revset: speed up existence checks for ordered filtered sets

Previously, calling 'if foo:' on a ordered filtered set would start iterating in
whatever the current direction was and return if a value was available. If the
current direction was ascending, but the set had a fastdesc available, this
meant we did a lot more work than necessary.

If this was applied without my previous max/min fixes, it would improve max()
performance (this was my first attempt at fixing the issue). Since those
previous fixes went in though, this doesn't have a visible benefit in the
benchmarks, but it does seem clearly better than it was before so I think it
should still go in.
Pierre-Yves David - Sept. 23, 2015, 8:23 a.m.
On 09/21/2015 07:17 PM, Durham Goode wrote:
> # HG changeset patch
> # User Durham Goode <durham@fb.com>
> # Date 1442793222 25200
> #      Sun Sep 20 16:53:42 2015 -0700
> # Node ID 9253d937b57d48c693c2820d914683efd2dfc00c
> # Parent  ab2a19c6961805bc67b0db2d615dc3fdfa949cb8
> revset: speed up existence checks for ordered filtered sets

I've queued this two with a third changesets removing implicit None 
check that Durham and I agreed on.

I've run revset benchmark on small repo, some positive impact is visible:

revset #0: draft() and ::tip
    min           max
0) 0.001971      0.001991
1) 0.001965      0.000428  21%

revset #1: ::tip and draft()
    min           max
0) 0.002017      0.001912
1) 0.001896  94% 0.000421  22%

revset #2: author(lmoscovicz)
    min           max
0) 1.049033      1.358913
1) 1.042508      0.319824  23%

revset #3: author(lmoscovicz) or author(mpm)
    min           max
0) 1.042512      1.367432
1) 1.019750      0.327750  23%

revset #4: author(mpm) or author(lmoscovicz)
    min           max
0) 1.050135      0.324924
1) 1.070698      0.319913

revset #5: roots((tip~100::) - (tip~100::tip))
    min           max
0) 0.000671      0.001018
1) 0.000605  90% 0.000946  92%

revset #6: roots((0::) - (0::tip))
    min           max
0) 0.149714      0.152369
1) 0.098677  65% 0.100374  65%

revset #7: (20000::) - (20000)
    min           max
0) 0.051019      0.042747
1) 0.035586  69% 0.016267  38%

Patch

diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -3113,7 +3113,12 @@  class filteredset(abstractsmartset):
         return lambda: self._iterfilter(it())
 
     def __nonzero__(self):
-        for r in self:
+        it = self
+        fast = self.fastasc or self.fastdesc
+        if fast:
+            it = fast()
+
+        for r in it:
             return True
         return False