Author: Lukas Diekmann <[email protected]>
Branch:
Changeset: r50310:f19d06a5972d
Date: 2011-12-08 17:27 +0100
http://bitbucket.org/pypy/pypy/changeset/f19d06a5972d/
Log: (l.diekmann, cfbolz): Be more careful about unrolling getitems. also
make one less copy
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
@@ -9,8 +9,9 @@
from pypy.interpreter import gateway, baseobjspace
from pypy.rlib.objectmodel import instantiate, specialize
from pypy.rlib.listsort import make_timsort_class
-from pypy.rlib import rerased, jit
+from pypy.rlib import rerased, jit, debug
from pypy.interpreter.argument import Signature
+from pypy.tool.sourcetools import func_with_new_name
UNROLL_CUTOFF = 5
@@ -170,6 +171,19 @@
share with the storage, if possible."""
return self.strategy.getitems(self)
+ def getitems_fixedsize(self):
+ """Returns a fixed-size list of all items after wrapping them."""
+ l = self.strategy.getitems_fixedsize(self)
+ debug.make_sure_not_resized(l)
+ return l
+
+ def getitems_unroll(self):
+ """Returns a fixed-size list of all items after wrapping them. The JIT
+ will fully unroll this function. """
+ l = self.strategy.getitems_unroll(self)
+ debug.make_sure_not_resized(l)
+ return l
+
def getitems_copy(self):
"""Returns a copy of all items in the list. Same as getitems except for
ObjectListStrategy."""
@@ -366,6 +380,8 @@
def getitems_copy(self, w_list):
return []
+ getitems_fixedsize = func_with_new_name(getitems_copy,
"getitems_fixedsize")
+ getitems_unroll = getitems_fixedsize
def getstorage_copy(self, w_list):
return self.erase(None)
@@ -496,7 +512,6 @@
# tuple is unmutable
return w_list.lstorage
-
@specialize.arg(2)
def _getitems_range(self, w_list, wrap_items):
l = self.unerase(w_list.lstorage)
@@ -519,6 +534,13 @@
return r
+ @jit.dont_look_inside
+ def getitems_fixedsize(self, w_list):
+ return self._getitems_range_unroll(w_list, True)
+ def getitems_unroll(self, w_list):
+ return self._getitems_range_unroll(w_list, True)
+ _getitems_range_unroll =
jit.unroll_safe(func_with_new_name(_getitems_range, "_getitems_range_unroll"))
+
def getslice(self, w_list, start, stop, step, length):
v = self.unerase(w_list.lstorage)
old_start = v[0]
@@ -676,6 +698,13 @@
def getitems_copy(self, w_list):
return [self.wrap(item) for item in self.unerase(w_list.lstorage)]
+ @jit.unroll_safe
+ def getitems_unroll(self, w_list):
+ return [self.wrap(item) for item in self.unerase(w_list.lstorage)]
+ @jit.dont_look_inside
+ def getitems_fixedsize(self, w_list):
+ return self.getitems_unroll(w_list)
+
def getstorage_copy(self, w_list):
items = self.unerase(w_list.lstorage)[:]
return self.erase(items)
diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py
--- a/pypy/objspace/std/objspace.py
+++ b/pypy/objspace/std/objspace.py
@@ -408,8 +408,10 @@
if isinstance(w_obj, W_TupleObject):
t = w_obj.wrappeditems
elif isinstance(w_obj, W_ListObject):
- # XXX this can copy twice
- t = w_obj.getitems()[:]
+ if unroll:
+ t = w_obj.getitems_unroll()
+ else:
+ t = w_obj.getitems_fixedsize()
else:
if unroll:
return make_sure_not_resized(ObjSpace.unpackiterable_unroll(
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
@@ -48,6 +48,46 @@
for i in range(7):
assert self.space.eq_w(l[i], l2[i])
+ def test_getitems_fixedsize(self):
+ w = self.space.wrap
+ from pypy.objspace.std.listobject import make_range_list
+ rangelist = make_range_list(self.space, 1,1,7)
+ emptylist = W_ListObject(self.space, [])
+ intlist = W_ListObject(self.space,
[w(1),w(2),w(3),w(4),w(5),w(6),w(7)])
+ strlist = W_ListObject(self.space,
[w('1'),w('2'),w('3'),w('4'),w('5'),w('6'),w('7')])
+ floatlist = W_ListObject(self.space,
[w(1.0),w(2.0),w(3.0),w(4.0),w(5.0),w(6.0),w(7.0)])
+ objlist = W_ListObject(self.space,
[w(1),w('2'),w(3.0),w(4),w(5),w(6),w(7)])
+
+ emptylist_copy = emptylist.getitems_fixedsize()
+ assert emptylist_copy == []
+
+ rangelist_copy = rangelist.getitems_fixedsize()
+ intlist_copy = intlist.getitems_fixedsize()
+ strlist_copy = strlist.getitems_fixedsize()
+ floatlist_copy = floatlist.getitems_fixedsize()
+ objlist_copy = objlist.getitems_fixedsize()
+ for i in range(7):
+ assert self.space.eq_w(rangelist_copy[i], rangelist.getitem(i))
+ assert self.space.eq_w(intlist_copy[i], intlist.getitem(i))
+ assert self.space.eq_w(strlist_copy[i], strlist.getitem(i))
+ assert self.space.eq_w(floatlist_copy[i], floatlist.getitem(i))
+ assert self.space.eq_w(objlist_copy[i], objlist.getitem(i))
+
+ emptylist_copy = emptylist.getitems_unroll()
+ assert emptylist_copy == []
+
+ rangelist_copy = rangelist.getitems_unroll()
+ intlist_copy = intlist.getitems_unroll()
+ strlist_copy = strlist.getitems_unroll()
+ floatlist_copy = floatlist.getitems_unroll()
+ objlist_copy = objlist.getitems_unroll()
+ for i in range(7):
+ assert self.space.eq_w(rangelist_copy[i], rangelist.getitem(i))
+ assert self.space.eq_w(intlist_copy[i], intlist.getitem(i))
+ assert self.space.eq_w(strlist_copy[i], strlist.getitem(i))
+ assert self.space.eq_w(floatlist_copy[i], floatlist.getitem(i))
+ assert self.space.eq_w(objlist_copy[i], objlist.getitem(i))
+
def test_random_getitem(self):
w = self.space.wrap
s = list('qedx387tn3uixhvt 7fh387fymh3dh238 dwd-wq.dwq9')
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit