[pypy-commit] pypy length-hint: abandon unpackiterable_into for direct rpython iterators (thanks fijal)

pjenvey noreply at buildbot.pypy.org
Fri Sep 14 03:32:56 CEST 2012


Author: Philip Jenvey <pjenvey at underboss.org>
Branch: length-hint
Changeset: r57335:3b78988e297c
Date: 2012-09-13 18:32 -0700
http://bitbucket.org/pypy/pypy/changeset/3b78988e297c/

Log:	abandon unpackiterable_into for direct rpython iterators (thanks
	fijal)

diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -7,8 +7,8 @@
 from pypy.interpreter.miscutils import ThreadLocals
 from pypy.tool.cache import Cache
 from pypy.tool.uid import HUGEVAL_BYTES
-from pypy.rlib.objectmodel import (compute_unique_id, resizelist_hint,
-                                   we_are_translated)
+from pypy.rlib.objectmodel import we_are_translated, newlist_hint,\
+     compute_unique_id
 from pypy.rlib.debug import make_sure_not_resized
 from pypy.rlib.timer import DummyTimer, Timer
 from pypy.rlib.rarithmetic import r_uint
@@ -837,45 +837,34 @@
         """Unpack an iterable into a real (interpreter-level) list.
 
         Raise an OperationError(w_ValueError) if the length is wrong."""
+        w_iterator = self.iter(w_iterable)
         if expected_length == -1:
-            lst_w = []
-            self.unpackiterable_into(w_iterable, lst_w)
-            return lst_w
-
-        lst_w = self._unpackiterable_known_length(self.iter(w_iterable),
-                                                  expected_length)
-        return lst_w[:]     # make the resulting list resizable
-
-    def unpackiterable_into(self, w_iterable, lst_w):
-        """Unpack an iterable into a pre-existing real
-        (interpreter-level) list.
-        """
-        w_iterator = self.iter(w_iterable)
-        # xxx special hack for speed
-        from pypy.interpreter.generator import GeneratorIterator
-        if isinstance(w_iterator, GeneratorIterator):
-            # XXX: hint?
-            w_iterator.unpack_into(lst_w)
-            return
-        # /xxx
-        self._unpackiterable_into_unknown_length(w_iterator, w_iterable,
-                                                 lst_w)
+            # xxx special hack for speed
+            from pypy.interpreter.generator import GeneratorIterator
+            if isinstance(w_iterator, GeneratorIterator):
+                lst_w = []
+                w_iterator.unpack_into(lst_w)
+                return lst_w
+            # /xxx
+            return self._unpackiterable_unknown_length(w_iterator, w_iterable)
+        else:
+            lst_w = self._unpackiterable_known_length(w_iterator,
+                                                      expected_length)
+            return lst_w[:]     # make the resulting list resizable
 
     def iteriterable(self, w_iterable):
         return W_InterpIterable(self, w_iterable)
 
-    def _unpackiterable_into_unknown_length(self, w_iterator, w_iterable, items):
+    def _unpackiterable_unknown_length(self, w_iterator, w_iterable):
         """Unpack an iterable of unknown length into an interp-level
         list.
         """
         # If we can guess the expected length we can preallocate.
         from pypy.objspace.std.iterobject import length_hint
-        newlen = len(items) + length_hint(self, w_iterable, 0)
-        #newlen = len(items) + self.length_hint(w_iterable, 0)
         try:
-            resizelist_hint(items, newlen)
+            items = newlist_hint(length_hint(self, w_iterable, 0))
         except MemoryError:
-            pass # it might have lied
+            items = [] # it might have lied
 
         tp = self.type(w_iterator)
         while True:
@@ -890,7 +879,6 @@
                 break  # done
             items.append(w_item)
         #
-        # XXX: resizelist_hint again if necessary
         return items
 
     @jit.dont_look_inside
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
@@ -3,11 +3,13 @@
 from pypy.objspace.std.multimethod import FailedToImplement
 from pypy.interpreter.error import OperationError, operationerrfmt
 from pypy.objspace.std.inttype import wrapint
+from pypy.objspace.std.iterobject import length_hint
 from pypy.objspace.std.listtype import get_list_index
 from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
 from pypy.objspace.std import slicetype
 from pypy.interpreter import gateway, baseobjspace
-from pypy.rlib.objectmodel import instantiate, specialize, newlist_hint
+from pypy.rlib.objectmodel import (instantiate, newlist_hint, specialize,
+                                   resizelist_hint)
 from pypy.rlib.listsort import make_timsort_class
 from pypy.rlib import rerased, jit, debug
 from pypy.interpreter.argument import Signature
@@ -798,20 +800,15 @@
 
     def extend(self, w_list, w_any):
         if isinstance(w_any, W_ListObject):
-            self.extend_list(w_list, w_any)
-            return
+            self._extend_list(w_list, w_any)
+        else:
+            newlen = w_list.length() + length_hint(self.space, w_any, 0)
+            resizelist_hint(self.unerase(w_list.lstorage), newlen)
+            for item in self.space.iteriterable(w_any):
+                w_list.append(item)
+            # XXX: resizelist_hint again if necessary
 
-        if self is not self.space.fromcache(ObjectListStrategy):
-            # XXX: force ObjectListStrategy for now
-            w_list.switch_to_object_strategy()
-            w_list.extend(w_any)
-            return
-
-        # XXX:
-        l = self.unerase(w_list.lstorage)
-        self.space.unpackiterable_into(w_any, l)
-
-    def extend_list(self, w_list, w_other):
+    def _extend_list(self, w_list, w_other):
         l = self.unerase(w_list.lstorage)
         if self.list_is_correct_type(w_other):
             l += self.unerase(w_other.lstorage)


More information about the pypy-commit mailing list