[pypy-commit] pypy list-strategies: Use TimSort as mixin, to have a specialized TimSort for each ListStrategy

l.diekmann noreply at buildbot.pypy.org
Fri Sep 23 13:15:10 CEST 2011


Author: Lukas Diekmann <lukas.diekmann at uni-duesseldorf.de>
Branch: list-strategies
Changeset: r47538:fb8088c4a857
Date: 2011-09-08 11:15 +0200
http://bitbucket.org/pypy/pypy/changeset/fb8088c4a857/

Log:	Use TimSort as mixin, to have a specialized TimSort for each
	ListStrategy

diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py
--- a/pypy/objspace/std/listobject.py
+++ b/pypy/objspace/std/listobject.py
@@ -8,7 +8,7 @@
 from pypy.objspace.std import slicetype
 from pypy.interpreter import gateway, baseobjspace
 from pypy.rlib.objectmodel import instantiate, specialize
-from pypy.rlib.listsort import TimSort
+from pypy.rlib.listsort import TimSort, BaseTimSort
 from pypy.rlib import rerased
 from pypy.interpreter.argument import Signature
 
@@ -153,6 +153,9 @@
     def reverse(self):
         self.strategy.reverse(self)
 
+    def sort(self, reverse):
+        self.strategy.sort(self, reverse)
+
 registerimplementation(W_ListObject)
 
 
@@ -221,6 +224,9 @@
     def reverse(self, w_list):
         raise NotImplementedError
 
+    def sort(self, w_list, reverse):
+        raise NotImplementedError
+
 class EmptyListStrategy(ListStrategy):
 
     def __init__(self, space):
@@ -789,6 +795,13 @@
             self.quicksort(l, start, p - 1)
             self.quicksort(l, p + 1, end)
 
+    def sort(self, w_list, reverse):
+        l = self.cast_from_void_star(w_list.lstorage)
+        sorter = IntSort(l, len(l))
+        sorter.sort()
+        if reverse:
+            l.reverse()
+
 class StringListStrategy(AbstractUnwrappedStrategy, ListStrategy):
     _none_value = None
 
@@ -808,6 +821,13 @@
     def list_is_correct_type(self, w_list):
         return w_list.strategy is self.space.fromcache(StringListStrategy)
 
+    def sort(self, w_list, reverse):
+        l = self.cast_from_void_star(w_list.lstorage)
+        sorter = StringSort(l, len(l))
+        sorter.sort()
+        if reverse:
+            l.reverse()
+
 # _______________________________________________________
 
 init_signature = Signature(['sequence'], None, None)
@@ -1160,7 +1180,15 @@
         space = self.space
         return space.is_true(space.lt(a, b))
 
-class IntSort(SimpleSort):
+class IntSort(BaseTimSort):
+    def lt(self, a, b):
+        return a < b
+
+class StringSort(BaseTimSort):
+    def lt(self, a, b):
+        return a < b
+
+class OldIntSort(SimpleSort):
     def lt(self, w_int1, w_int2):
         from pypy.objspace.std.intobject import W_IntObject
         assert isinstance(w_int1, W_IntObject)
@@ -1168,7 +1196,7 @@
         space = self.space
         return w_int1.intval < w_int2.intval
 
-class StringSort(SimpleSort):
+class OldStringSort(SimpleSort):
     def lt(self, w_str1, w_str2):
         from pypy.objspace.std.stringobject import W_StringObject
         assert isinstance(w_str1, W_StringObject)
@@ -1221,12 +1249,14 @@
             sorterclass = CustomKeySort
         else:
             if w_list.strategy is space.fromcache(IntegerListStrategy):
-                sorterclass = IntSort
+                w_list.sort(has_reverse)
+                return space.w_None
             elif w_list.strategy is space.fromcache(StringListStrategy):
-                sorterclass = StringSort
+                w_list.sort(has_reverse)
+                return space.w_None
             else:
                 sorterclass = SimpleSort
-    #XXX optimize this, getitems is bad
+
     sorter = sorterclass(w_list.getitems(), w_list.length())
     sorter.space = space
     sorter.w_cmp = w_cmp
diff --git a/pypy/rlib/listsort.py b/pypy/rlib/listsort.py
--- a/pypy/rlib/listsort.py
+++ b/pypy/rlib/listsort.py
@@ -11,7 +11,10 @@
 ## this class has to be used carefully, because all the lists that are
 ## sorted will be unified
 
-class TimSort:
+class BaseTimSort:
+
+    _mixin_ = True
+
     """TimSort(list).sort()
 
     Sorts the list in-place, using the overridable method lt() for comparison.
@@ -23,9 +26,6 @@
             listlength = len(list)
         self.listlength = listlength
 
-    def lt(self, a, b):
-        return a < b
-
     def le(self, a, b):
         return not self.lt(b, a)   # always use self.lt() as the primitive
 
@@ -554,6 +554,11 @@
         assert self.pending[0].len == self.listlength
 
 
+class TimSort(BaseTimSort):
+
+    def lt(self, a, b):
+        return a < b
+
 class ListSlice:
     "A sublist of a list."
 


More information about the pypy-commit mailing list