Patchwork [4,of,5] smartset: micro optimize baseset.slice() to use slice of list

login
register
mail settings
Submitter Yuya Nishihara
Date June 13, 2017, 2:15 p.m.
Message ID <72a4a69c2d18c0cba339.1497363358@mimosa>
Download mbox | patch
Permalink /patch/21358/
State Accepted
Headers show

Comments

Yuya Nishihara - June 13, 2017, 2:15 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1428591366 -32400
#      Thu Apr 09 23:56:06 2015 +0900
# Node ID 72a4a69c2d18c0cba33956a634c9d3e56ecd9bf9
# Parent  ee516ca46910c78731bd53ba034dcd6c519f76b2
smartset: micro optimize baseset.slice() to use slice of list

-1ms isn't significant, but seems not bad.

  revset #1: limit(0::9999, 100, 9000)
  5) 0.001681
  6) 0.000790

Patch

diff --git a/mercurial/smartset.py b/mercurial/smartset.py
--- a/mercurial/smartset.py
+++ b/mercurial/smartset.py
@@ -372,6 +372,18 @@  class baseset(abstractsmartset):
     def __sub__(self, other):
         return self._fastsetop(other, '__sub__')
 
+    def _slice(self, start, stop):
+        # creating new list should be generally cheaper than iterating items
+        if self._ascending is None:
+            return baseset(self._list[start:stop], istopo=self._istopo)
+
+        data = self._asclist
+        if not self._ascending:
+            start, stop = max(len(data) - stop, 0), max(len(data) - start, 0)
+        s = baseset(data[start:stop], istopo=self._istopo)
+        s._ascending = self._ascending
+        return s
+
     def __repr__(self):
         d = {None: '', False: '-', True: '+'}[self._ascending]
         s = _formatsetrepr(self._datarepr)
diff --git a/tests/test-revset.t b/tests/test-revset.t
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -1037,6 +1037,49 @@  Test smartset.slice() by first/last()
   6
   7
 
+ (using baseset)
+
+  $ hg debugrevspec --no-show-revs -s 0+1+2+3+4+5+6+7
+  * set:
+  <baseset [0, 1, 2, 3, 4, 5, 6, 7]>
+  $ hg debugrevspec --no-show-revs -s 0::7
+  * set:
+  <baseset+ [0, 1, 2, 3, 4, 5, 6, 7]>
+  $ log 'limit(0+1+2+3+4+5+6+7, 3, 4)'
+  4
+  5
+  6
+  $ log 'limit(sort(0::7, rev), 3, 4)'
+  4
+  5
+  6
+  $ log 'limit(sort(0::7, -rev), 3, 4)'
+  3
+  2
+  1
+  $ log 'last(sort(0::7, rev), 2)'
+  6
+  7
+  $ hg debugrevspec -s 'limit(sort(0::7, rev), 3, 6)'
+  * set:
+  <baseset+ [6, 7]>
+  6
+  7
+  $ hg debugrevspec -s 'limit(sort(0::7, rev), 3, 9)'
+  * set:
+  <baseset+ []>
+  $ hg debugrevspec -s 'limit(sort(0::7, -rev), 3, 6)'
+  * set:
+  <baseset- [0, 1]>
+  1
+  0
+  $ hg debugrevspec -s 'limit(sort(0::7, -rev), 3, 9)'
+  * set:
+  <baseset- []>
+  $ hg debugrevspec -s 'limit(0::7, 0)'
+  * set:
+  <baseset+ []>
+
 Test order of first/last revisions
 
   $ hg debugrevspec -s 'first(4:0, 3) & 3:'
@@ -1967,8 +2010,7 @@  ordering defined by it.
     define)
   * set:
   <filteredset
-    <baseset slice=0:1
-      <baseset [1, 0, 2]>>,
+    <baseset [1]>,
     <spanset- 0:3>>
   1
 
@@ -2003,8 +2045,7 @@  ordering defined by it.
   <filteredset
     <spanset- 0:3>,
     <not
-      <baseset slice=0:1
-        <baseset [1, 2, 0]>>>>
+      <baseset [1]>>>
   2
   0
 
@@ -3628,8 +3669,7 @@  issue2549 - correct optimizations
       ('symbol', '2')))
   * set:
   <filteredset
-    <baseset slice=0:2
-      <baseset [1, 2, 3]>>,
+    <baseset [1, 2]>,
     <not
       <baseset [2]>>>
   1
@@ -3683,8 +3723,7 @@  issue2549 - correct optimizations
       ('symbol', '2')))
   * set:
   <filteredset
-    <baseset slice=0:1
-      <baseset [2, 1]>>,
+    <baseset [2]>,
     <not
       <baseset [2]>>>