[pypy-commit] pypy list-strategies: Optimized add__List_List to not use getitems anymore

l.diekmann noreply at buildbot.pypy.org
Fri Sep 23 13:12:58 CEST 2011


Author: Lukas Diekmann <lukas.diekmann at uni-duesseldorf.de>
Branch: list-strategies
Changeset: r47490:6ce154248735
Date: 2011-03-29 17:17 +0200
http://bitbucket.org/pypy/pypy/changeset/6ce154248735/

Log:	Optimized add__List_List to not use getitems anymore

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
@@ -86,6 +86,9 @@
             self.strategy = self.space.fromcache(EmptyListStrategy)
             self.strategy.init_from_list_w(self, [])
 
+    def clone(self):
+        return self.strategy.clone(self)
+
     def copy_into(self, other):
         self.strategy.copy_into(self, other)
     # ___________________________________________________
@@ -147,6 +150,9 @@
     def init_from_list_w(self, w_list, list_w):
         raise NotImplementedError
 
+    def clone(self, w_list):
+        raise NotImplementedError
+
     def copy_into(self, w_list, w_other):
         raise NotImplementedError
 
@@ -205,6 +211,9 @@
     cast_to_void_star = staticmethod(cast_to_void_star)
     cast_from_void_star = staticmethod(cast_from_void_star)
 
+    def clone(self, w_list):
+        return W_ListObject.from_storage_and_strategy(self.space, w_list.lstorage, self)
+
     def copy_into(self, w_list, w_other):
         pass
 
@@ -275,6 +284,10 @@
     cast_to_void_star = staticmethod(cast_to_void_star)
     cast_from_void_star = staticmethod(cast_from_void_star)
 
+    def clone(self, w_list):
+        storage = w_list.lstorage # lstorage is tuple, no need to clone
+        w_clone = W_ListObject.from_storage_and_strategy(self.space, storage, self)
+
     def copy_into(self, w_list, w_other):
         w_other.strategy = self
         w_other.lstorage = w_list.lstorage
@@ -429,6 +442,12 @@
         l = [self.unwrap(w_item) for w_item in list_w]
         w_list.lstorage = self.cast_to_void_star(l)
 
+    def clone(self, w_list):
+        l = self.cast_from_void_star(w_list.lstorage)
+        storage = self.cast_to_void_star(l[:])
+        w_clone = W_ListObject.from_storage_and_strategy(self.space, storage, self)
+        return w_clone
+
     def copy_into(self, w_list, w_other):
         w_other.strategy = self
         items = self.cast_from_void_star(w_list.lstorage)[:]
@@ -761,7 +780,9 @@
     return iterobject.W_FastListIterObject(w_list)
 
 def add__List_List(space, w_list1, w_list2):
-    return W_ListObject(space, w_list1.getitems() + w_list2.getitems())
+    w_clone = w_list1.clone()
+    w_clone.extend(w_list2)
+    return w_clone
 
 
 def inplace_add__List_ANY(space, w_list1, w_iterable2):
diff --git a/pypy/objspace/std/test/test_liststrategies.py b/pypy/objspace/std/test/test_liststrategies.py
--- a/pypy/objspace/std/test/test_liststrategies.py
+++ b/pypy/objspace/std/test/test_liststrategies.py
@@ -244,3 +244,18 @@
         l2.append(self.space.wrap("four"))
         assert l2 == l1.getitems()
 
+    def test_clone(self):
+        l1 = W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)])
+        clone = l1.clone()
+        assert isinstance(clone.strategy, IntegerListStrategy)
+        clone.append(self.space.wrap(7))
+        assert not self.space.eq_w(l1, clone)
+
+    def test_add_does_not_use_getitems(self):
+        l1 = W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)])
+        l1.getitems = None
+        l2 = W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)])
+        l2.getitems = None
+        l3 = self.space.add(l1, l2)
+        l4 = W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3), self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)])
+        assert self.space.eq_w(l3, l4)


More information about the pypy-commit mailing list