[pypy-commit] pypy fast_cffi_list_init: add a fast-path also for floats. Also, remove the unnecessary copy in case of int lists, because now this is already guaranteed by unpackiterable_int
antocuni
noreply at buildbot.pypy.org
Thu Oct 10 16:26:42 CEST 2013
Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: fast_cffi_list_init
Changeset: r67294:474e7f3e7d2d
Date: 2013-10-10 16:25 +0200
http://bitbucket.org/pypy/pypy/changeset/474e7f3e7d2d/
Log: add a fast-path also for floats. Also, remove the unnecessary copy
in case of int lists, because now this is already guaranteed by
unpackiterable_int
diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py
--- a/pypy/module/_cffi_backend/cdataobj.py
+++ b/pypy/module/_cffi_backend/cdataobj.py
@@ -283,7 +283,10 @@
return self.ctype.iter(self)
def unpackiterable_int(self, space):
- return self.ctype.unpackiterable_int(self)
+ return self.ctype.aslist_int(self)
+
+ def unpackiterable_float(self, space):
+ return self.ctype.aslist_float(self)
@specialize.argtype(1)
def write_raw_signed_data(self, source):
diff --git a/pypy/module/_cffi_backend/ctypearray.py b/pypy/module/_cffi_backend/ctypearray.py
--- a/pypy/module/_cffi_backend/ctypearray.py
+++ b/pypy/module/_cffi_backend/ctypearray.py
@@ -105,7 +105,7 @@
def iter(self, cdata):
return W_CDataIter(self.space, self.ctitem, cdata)
- def unpackiterable_int(self, cdata):
+ def aslist_int(self, cdata):
from rpython.rlib.rarray import populate_list_from_raw_array
if self.ctitem.is_long():
res = []
@@ -115,6 +115,16 @@
return res
return None
+ def aslist_float(self, cdata):
+ from rpython.rlib.rarray import populate_list_from_raw_array
+ if self.ctitem.is_double():
+ res = []
+ buf = rffi.cast(rffi.DOUBLEP, cdata._cdata)
+ length = cdata.get_array_length()
+ populate_list_from_raw_array(res, buf, length)
+ return res
+ return None
+
def get_vararg_type(self):
return self.ctptr
diff --git a/pypy/module/_cffi_backend/test/test_extra.py b/pypy/module/_cffi_backend/test/test_extra.py
--- a/pypy/module/_cffi_backend/test/test_extra.py
+++ b/pypy/module/_cffi_backend/test/test_extra.py
@@ -71,3 +71,16 @@
lst = list(buf)
assert lst == [1, 2, 3]
assert self.get_count() == 1
+
+ def test_list_float(self):
+ import _cffi_backend
+ DOUBLE = _cffi_backend.new_primitive_type('double')
+ P_DOUBLE = _cffi_backend.new_pointer_type(DOUBLE)
+ DOUBLE_ARRAY = _cffi_backend.new_array_type(P_DOUBLE, 3)
+ buf = _cffi_backend.newp(DOUBLE_ARRAY)
+ buf[0] = 1.1
+ buf[1] = 2.2
+ buf[2] = 3.3
+ lst = list(buf)
+ assert lst == [1.1, 2.2, 3.3]
+ assert self.get_count() == 1
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
@@ -949,13 +949,16 @@
w_list.__init__(space, w_iterable.getitems_copy())
return
- intlist = space.listview_int(w_iterable)
- if intlist is None:
- intlist = space.unpackiterable_int(w_iterable)
+ intlist = space.unpackiterable_int(w_iterable)
if intlist is not None:
w_list.strategy = strategy = space.fromcache(IntegerListStrategy)
- # need to copy because intlist can share with w_iterable
- w_list.lstorage = strategy.erase(intlist[:])
+ w_list.lstorage = strategy.erase(intlist)
+ return
+
+ floatlist = space.unpackiterable_float(w_iterable)
+ if floatlist is not None:
+ w_list.strategy = strategy = space.fromcache(FloatListStrategy)
+ w_list.lstorage = strategy.erase(floatlist)
return
strlist = space.listview_str(w_iterable)
More information about the pypy-commit
mailing list