[pypy-svn] r50330 - pypy/dist/pypy/objspace/std

arigo at codespeak.net arigo at codespeak.net
Fri Jan 4 19:01:28 CET 2008


Author: arigo
Date: Fri Jan  4 19:01:27 2008
New Revision: 50330

Modified:
   pypy/dist/pypy/objspace/std/iterobject.py
   pypy/dist/pypy/objspace/std/itertype.py
   pypy/dist/pypy/objspace/std/listobject.py
   pypy/dist/pypy/objspace/std/model.py
   pypy/dist/pypy/objspace/std/tupleobject.py
Log:
A W_FastSeqIterObject that is a lot more efficient
than the W_SeqIterObject for lists and tuples.


Modified: pypy/dist/pypy/objspace/std/iterobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/iterobject.py	(original)
+++ pypy/dist/pypy/objspace/std/iterobject.py	Fri Jan  4 19:01:27 2008
@@ -7,13 +7,26 @@
 from pypy.objspace.std.objspace import *
 
 
-class W_SeqIterObject(W_Object):
+class W_AbstractSeqIterObject(W_Object):
     from pypy.objspace.std.itertype import iter_typedef as typedef
     
     def __init__(w_self, w_seq, index=0):
+        if index < 0:
+            index = 0
         w_self.w_seq = w_seq
         w_self.index = index
 
+class W_SeqIterObject(W_AbstractSeqIterObject):
+    """Sequence iterator implementation for general sequences."""
+
+class W_FastSeqIterObject(W_AbstractSeqIterObject):
+    """Sequence iterator specialized for lists or tuples, accessing
+    directly their RPython-level list of wrapped objects.
+    """
+    def __init__(w_self, w_seq, wrappeditems):
+        W_AbstractSeqIterObject.__init__(w_self, w_seq)
+        w_self.wrappeditems = wrappeditems
+
 class W_ReverseSeqIterObject(W_Object):
     from pypy.objspace.std.itertype import reverse_iter_typedef as typedef
     
@@ -24,6 +37,7 @@
 
 
 registerimplementation(W_SeqIterObject)
+registerimplementation(W_FastSeqIterObject)
 registerimplementation(W_ReverseSeqIterObject)
 
 def iter__SeqIter(space, w_seqiter):
@@ -52,6 +66,33 @@
         w_len = space.wrap(0)
     return w_len
 
+
+def iter__FastSeqIter(space, w_seqiter):
+    return w_seqiter
+
+def next__FastSeqIter(space, w_seqiter):
+    if w_seqiter.wrappeditems is None:
+        raise OperationError(space.w_StopIteration, space.w_None)
+    index = w_seqiter.index
+    try:
+        w_item = w_seqiter.wrappeditems[index]
+    except IndexError:
+        w_seqiter.wrappeditems = None
+        w_seqiter.w_seq = None
+        raise OperationError(space.w_StopIteration, space.w_None) 
+    w_seqiter.index = index + 1
+    return w_item
+
+def len__FastSeqIter(space, w_seqiter):
+    if w_seqiter.wrappeditems is None:
+        return space.wrap(0)
+    totallength = len(w_seqiter.wrappeditems)
+    remaining = totallength - w_seqiter.index
+    if remaining < 0:
+        remaining = 0
+    return space.wrap(remaining)
+
+
 def iter__ReverseSeqIter(space, w_seqiter):
     return w_seqiter
 

Modified: pypy/dist/pypy/objspace/std/itertype.py
==============================================================================
--- pypy/dist/pypy/objspace/std/itertype.py	(original)
+++ pypy/dist/pypy/objspace/std/itertype.py	Fri Jan  4 19:01:27 2008
@@ -7,8 +7,8 @@
     XXX to do: remove this __reduce__ method and do
     a registration with copy_reg, instead.
     """
-    from pypy.objspace.std.iterobject import W_SeqIterObject
-    assert isinstance(w_self, W_SeqIterObject)
+    from pypy.objspace.std.iterobject import W_AbstractSeqIterObject
+    assert isinstance(w_self, W_AbstractSeqIterObject)
     from pypy.interpreter.mixedmodule import MixedModule
     w_mod    = space.getbuiltinmodule('_pickle_support')
     mod      = space.interp_w(MixedModule, w_mod)
@@ -44,9 +44,11 @@
     __reduce__ = gateway.interp2app(descr_seqiter__reduce__,
                            unwrap_spec=[gateway.W_Root, gateway.ObjSpace]),
     )
+iter_typedef.acceptable_as_base_class = False
 
 reverse_iter_typedef = StdTypeDef("reversesequenceiterator",
 
     __reduce__ = gateway.interp2app(descr_reverseseqiter__reduce__,
                            unwrap_spec=[gateway.W_Root, gateway.ObjSpace]),
     )
+reverse_iter_typedef.acceptable_as_base_class = False

Modified: pypy/dist/pypy/objspace/std/listobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/listobject.py	(original)
+++ pypy/dist/pypy/objspace/std/listobject.py	Fri Jan  4 19:01:27 2008
@@ -33,10 +33,26 @@
     w_iterable, = __args__.parse('list',
                                (['sequence'], None, None),   # signature
                                [EMPTY_LIST])                 # default argument
-    if w_iterable is EMPTY_LIST:
-        w_list.wrappeditems = []
-    else:
-        w_list.wrappeditems = space.unpackiterable(w_iterable)
+    #
+    # this is the old version of the loop at the end of this function:
+    #
+    #   w_list.wrappeditems = space.unpackiterable(w_iterable)
+    #
+    # This is commented out to avoid assigning a new RPython list to
+    # 'wrappeditems', which defeats the W_FastSeqIterObject optimization.
+    #
+    items_w = w_list.wrappeditems
+    del items_w[:]
+    if w_iterable is not EMPTY_LIST:
+        w_iterator = space.iter(w_iterable)
+        while True:
+            try:
+                w_item = space.next(w_iterator)
+            except OperationError, e:
+                if not e.match(space, space.w_StopIteration):
+                    raise
+                break  # done
+            items_w.append(w_item)
 
 def len__List(space, w_list):
     result = len(w_list.wrappeditems)
@@ -76,7 +92,7 @@
 
 def iter__List(space, w_list):
     from pypy.objspace.std import iterobject
-    return iterobject.W_SeqIterObject(w_list)
+    return iterobject.W_FastSeqIterObject(w_list, w_list.wrappeditems)
 
 def add__List_List(space, w_list1, w_list2):
     return W_ListObject(w_list1.wrappeditems + w_list2.wrappeditems)

Modified: pypy/dist/pypy/objspace/std/model.py
==============================================================================
--- pypy/dist/pypy/objspace/std/model.py	(original)
+++ pypy/dist/pypy/objspace/std/model.py	Fri Jan  4 19:01:27 2008
@@ -103,6 +103,7 @@
             longobject.W_LongObject: [],
             noneobject.W_NoneObject: [],
             iterobject.W_SeqIterObject: [],
+            iterobject.W_FastSeqIterObject: [],
             iterobject.W_ReverseSeqIterObject: [],
             unicodeobject.W_UnicodeObject: [],
             dictproxyobject.W_DictProxyObject: [],

Modified: pypy/dist/pypy/objspace/std/tupleobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/tupleobject.py	(original)
+++ pypy/dist/pypy/objspace/std/tupleobject.py	Fri Jan  4 19:01:27 2008
@@ -60,7 +60,7 @@
 
 def iter__Tuple(space, w_tuple):
     from pypy.objspace.std import iterobject
-    return iterobject.W_SeqIterObject(w_tuple)
+    return iterobject.W_FastSeqIterObject(w_tuple, w_tuple.wrappeditems)
 
 def add__Tuple_Tuple(space, w_tuple1, w_tuple2):
     items1 = w_tuple1.wrappeditems


More information about the pypy-svn mailing list