Author: Lukas Diekmann <lukas.diekm...@uni-duesseldorf.de> 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 pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit