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

Reply via email to