Hi Anto, just said it on IRC, just so that it doesn't get lost:
I think module/_cffi_backend should use the generic interfaces and not touch the internals of listobject.py. it can just call space.listview_int and space.listview_float, they are a no-copy operation on int/float strategy lists. Cheers, Carl Friedrich On 09/10/13 18:24, antocuni wrote: > Author: Antonio Cuni <anto.c...@gmail.com> > Branch: fast_cffi_list_init > Changeset: r67250:a8d55ebf78ea > Date: 2013-10-09 18:20 +0200 > http://bitbucket.org/pypy/pypy/changeset/a8d55ebf78ea/ > > Log: implement the fast-path for intstrategy and long[] only > > diff --git a/pypy/module/_cffi_backend/ctypeprim.py > b/pypy/module/_cffi_backend/ctypeprim.py > --- a/pypy/module/_cffi_backend/ctypeprim.py > +++ b/pypy/module/_cffi_backend/ctypeprim.py > @@ -85,6 +85,11 @@ > return self.space.wrap(s) > return W_CType.string(self, cdataobj, maxlen) > > + def is_long(self): > + return False > + > + def is_double(self): > + return False > > class W_CTypePrimitiveCharOrUniChar(W_CTypePrimitive): > _attrs_ = [] > @@ -171,6 +176,9 @@ > self.vmin = r_uint(-1) << (sh - 1) > self.vrangemax = (r_uint(1) << sh) - 1 > > + def is_long(self): > + return self.size == rffi.sizeof(lltype.Signed) > + > def cast_to_int(self, cdata): > return self.convert_to_object(cdata) > > @@ -274,6 +282,9 @@ > class W_CTypePrimitiveFloat(W_CTypePrimitive): > _attrs_ = [] > > + def is_double(self): > + return self.size == rffi.sizeof(lltype.Float) > + > def cast(self, w_ob): > space = self.space > if isinstance(w_ob, cdataobj.W_CData): > diff --git a/pypy/module/_cffi_backend/ctypeptr.py > b/pypy/module/_cffi_backend/ctypeptr.py > --- a/pypy/module/_cffi_backend/ctypeptr.py > +++ b/pypy/module/_cffi_backend/ctypeptr.py > @@ -58,19 +58,44 @@ > value = rffi.cast(rffi.CCHARP, value) > return cdataobj.W_CData(space, value, self) > > + def _convert_array_from_list_strategy_maybe(self, cdata, w_ob): > + from rpython.rlib.rarray import copy_list_to_raw_array > + from pypy.objspace.std.listobject import W_ListObject, > IntegerListStrategy > + if not isinstance(w_ob, W_ListObject): > + return False > + # > + int_stragegy = self.space.fromcache(IntegerListStrategy) > + > + if w_ob.strategy is int_stragegy and self.ctitem.is_long(): > + int_list = w_ob.strategy.unerase(w_ob.lstorage) > + cdata = rffi.cast(rffi.LONGP, cdata) > + copy_list_to_raw_array(int_list, cdata) > + return True > + > + return False > + > + def _convert_array_from_listview(self, cdata, w_ob): > + space = self.space > + lst_w = space.listview(w_ob) > + if self.length >= 0 and len(lst_w) > self.length: > + raise operationerrfmt(space.w_IndexError, > + "too many initializers for '%s' (got %d)", > + self.name, len(lst_w)) > + ctitem = self.ctitem > + for i in range(len(lst_w)): > + ctitem.convert_from_object(cdata, lst_w[i]) > + cdata = rffi.ptradd(cdata, ctitem.size) > + > def convert_array_from_object(self, cdata, w_ob): > space = self.space > + if self._convert_array_from_list_strategy_maybe(cdata, w_ob): > + # the fast path worked, we are done now > + return > + # > + # continue with the slow path > if (space.isinstance_w(w_ob, space.w_list) or > space.isinstance_w(w_ob, space.w_tuple)): > - lst_w = space.listview(w_ob) > - if self.length >= 0 and len(lst_w) > self.length: > - raise operationerrfmt(space.w_IndexError, > - "too many initializers for '%s' (got %d)", > - self.name, len(lst_w)) > - ctitem = self.ctitem > - for i in range(len(lst_w)): > - ctitem.convert_from_object(cdata, lst_w[i]) > - cdata = rffi.ptradd(cdata, ctitem.size) > + self._convert_array_from_listview(cdata, w_ob) > elif (self.can_cast_anything or > (self.ctitem.is_primitive_integer and > self.ctitem.size == rffi.sizeof(lltype.Char))): > 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 > @@ -139,6 +139,8 @@ > > class W_ListObject(W_Root): > > + strategy = None > + > def __init__(self, space, wrappeditems, sizehint=-1): > assert isinstance(wrappeditems, list) > self.space = space > _______________________________________________ > pypy-commit mailing list > pypy-com...@python.org > https://mail.python.org/mailman/listinfo/pypy-commit > _______________________________________________ pypy-dev mailing list pypy-dev@python.org https://mail.python.org/mailman/listinfo/pypy-dev