[pypy-commit] pypy speedup-list-comprehension: remove sizehint on the list, use instead special strategy

fijal noreply at buildbot.pypy.org
Sat Feb 25 00:23:08 CET 2012


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: speedup-list-comprehension
Changeset: r52890:2617e06218fe
Date: 2012-02-24 12:49 -0700
http://bitbucket.org/pypy/pypy/changeset/2617e06218fe/

Log:	remove sizehint on the list, use instead special strategy

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
@@ -33,8 +33,10 @@
     return W_ListObject.from_storage_and_strategy(space, storage, strategy)
 
 @jit.look_inside_iff(lambda space, list_w: jit.isconstant(len(list_w)) and len(list_w) < UNROLL_CUTOFF)
-def get_strategy_from_list_objects(space, list_w):
+def get_strategy_from_list_objects(space, list_w, sizehint):
     if not list_w:
+        if sizehint != -1:
+            return SizeListStrategy(space, sizehint)
         return space.fromcache(EmptyListStrategy)
 
     # check for ints
@@ -80,10 +82,10 @@
         w_self.space = space
         if space.config.objspace.std.withliststrategies:
             w_self.strategy = get_strategy_from_list_objects(space,
-                                                             wrappeditems)
+                                                             wrappeditems,
+                                                             sizehint)
         else:
             w_self.strategy = space.fromcache(ObjectListStrategy)
-        w_self.sizehint = sizehint
         w_self.init_from_list_w(wrappeditems)
 
     @staticmethod
@@ -257,6 +259,7 @@
 
 
 class ListStrategy(object):
+    sizehint = 0
 
     def __init__(self, space):
         self.space = space
@@ -338,6 +341,7 @@
     def sort(self, w_list, reverse):
         raise NotImplementedError
 
+
 class EmptyListStrategy(ListStrategy):
     """EmptyListStrategy is used when a W_List withouth elements is created.
     The storage is None. When items are added to the W_List a new RPython list
@@ -399,7 +403,7 @@
         else:
             strategy = self.space.fromcache(ObjectListStrategy)
 
-        storage = strategy.get_empty_storage(w_list.sizehint)
+        storage = strategy.get_empty_storage(self.sizehint)
         w_list.strategy = strategy
         w_list.lstorage = storage
 
@@ -440,6 +444,13 @@
     def reverse(self, w_list):
         pass
 
+class SizeListStrategy(EmptyListStrategy):
+    """ Like empty, but when modified it'll preallocate the size to sizehint
+    """
+    def __init__(self, space, sizehint):
+        self.sizehint = sizehint
+        ListStrategy.__init__(self, space)
+
 class RangeListStrategy(ListStrategy):
     """RangeListStrategy is used when a list is created using the range method.
     The storage is a tuple containing only three integers start, step and length
diff --git a/pypy/objspace/std/test/test_listobject.py b/pypy/objspace/std/test/test_listobject.py
--- a/pypy/objspace/std/test/test_listobject.py
+++ b/pypy/objspace/std/test/test_listobject.py
@@ -1,6 +1,7 @@
 # coding: iso-8859-15
 import random
-from pypy.objspace.std.listobject import W_ListObject
+from pypy.objspace.std.listobject import W_ListObject, SizeListStrategy,\
+     IntegerListStrategy, ObjectListStrategy
 from pypy.interpreter.error import OperationError
 
 from pypy.conftest import gettestobjspace, option
@@ -390,6 +391,16 @@
         assert self.space.eq_w(self.space.le(w_list4, w_list3),
                            self.space.w_True)
 
+    def test_sizehint(self):
+        space = self.space
+        w_l = space.newlist([], sizehint=10)
+        assert isinstance(w_l.strategy, SizeListStrategy)
+        space.call_method(w_l, 'append', space.wrap(3))
+        assert isinstance(w_l.strategy, IntegerListStrategy)
+        w_l = space.newlist([], sizehint=10)
+        space.call_method(w_l, 'append', space.w_None)
+        assert isinstance(w_l.strategy, ObjectListStrategy)
+
 
 class AppTestW_ListObject(object):
     def setup_class(cls):


More information about the pypy-commit mailing list