Patchwork revset: changed last implementation to use lazy classes

login
register
mail settings
Submitter Lucas Moscovicz
Date Feb. 19, 2014, 9:15 p.m.
Message ID <98a3147bcb05e9284b8f.1392844552@dev1037.prn2.facebook.com>
Download mbox | patch
Permalink /patch/3702/
State Accepted
Headers show

Comments

Lucas Moscovicz - Feb. 19, 2014, 9:15 p.m.
# HG changeset patch
# User Lucas Moscovicz <lmoscovicz@fb.com>
# Date 1392843401 28800
#      Wed Feb 19 12:56:41 2014 -0800
# Node ID 98a3147bcb05e9284b8f704400479854079f2d67
# Parent  c29948fed40a2d9755ecaa01ec05bfa542f65670
revset: changed last implementation to use lazy classes

Instead of using getitem just reverse the revision list and get the first
'lim' elements. With classes like spanset which are easily reversible this
will work faster.

Performance Benchmarking:

$ time hg log -qr "last(all())"
...

real  0m0.569s
user  0m0.447s
sys 0m0.122s

$ time ./hg log -qr "last(all())"
...

real  0m0.215s
user  0m0.150s
sys 0m0.063s
Matt Mackall - Feb. 19, 2014, 10:47 p.m.
On Wed, 2014-02-19 at 13:15 -0800, Lucas Moscovicz wrote:
> # HG changeset patch
> # User Lucas Moscovicz <lmoscovicz@fb.com>
> # Date 1392843401 28800
> #      Wed Feb 19 12:56:41 2014 -0800
> # Node ID 98a3147bcb05e9284b8f704400479854079f2d67
> # Parent  c29948fed40a2d9755ecaa01ec05bfa542f65670
> revset: changed last implementation to use lazy classes

Queued for default, thanks.

Patch

diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -969,8 +969,18 @@ 
         # i18n: "last" is a keyword
         raise error.ParseError(_("last expects a number"))
     ss = subset.set()
-    os = getset(repo, spanset(repo), l[0])[-lim:]
-    return baseset([r for r in os if r in ss])
+    os = getset(repo, spanset(repo), l[0])
+    os.reverse()
+    bs = baseset([])
+    it = iter(os)
+    for x in xrange(lim):
+        try:
+            y = it.next()
+            if y in ss:
+                bs.append(y)
+        except (StopIteration):
+            break
+    return bs
 
 def maxrev(repo, subset, x):
     """``max(set)``