[pypy-commit] pypy default: Fast paths for unpack()
arigo
pypy.commits at gmail.com
Sun Apr 17 04:24:35 EDT 2016
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r83707:191f30d6a23d
Date: 2016-04-17 10:22 +0200
http://bitbucket.org/pypy/pypy/changeset/191f30d6a23d/
Log: Fast paths for unpack()
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -1029,6 +1029,9 @@
def newlist_int(self, list_i):
return self.newlist([self.wrap(i) for i in list_i])
+ def newlist_float(self, list_f):
+ return self.newlist([self.wrap(f) for f in list_f])
+
def newlist_hint(self, sizehint):
from pypy.objspace.std.listobject import make_empty_list_with_size
return make_empty_list_with_size(self, sizehint)
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
@@ -323,14 +323,18 @@
from pypy.module._cffi_backend import ctypearray
ctype = self.ctype
if isinstance(ctype, ctypearray.W_CTypeArray):
- return ctype.ctitem.unpack_list_of_int_items(self)
+ length = self.get_array_length()
+ with self as ptr:
+ return ctype.ctitem.unpack_list_of_int_items(ptr, length)
return None
def unpackiterable_float(self, space):
from pypy.module._cffi_backend import ctypearray
ctype = self.ctype
if isinstance(ctype, ctypearray.W_CTypeArray):
- return ctype.ctitem.unpack_list_of_float_items(self)
+ length = self.get_array_length()
+ with self as ptr:
+ return ctype.ctitem.unpack_list_of_float_items(ptr, length)
return None
@specialize.argtype(1)
diff --git a/pypy/module/_cffi_backend/ctypeobj.py b/pypy/module/_cffi_backend/ctypeobj.py
--- a/pypy/module/_cffi_backend/ctypeobj.py
+++ b/pypy/module/_cffi_backend/ctypeobj.py
@@ -49,10 +49,10 @@
def is_unichar_ptr_or_array(self):
return False
- def unpack_list_of_int_items(self, cdata):
+ def unpack_list_of_int_items(self, ptr, length):
return None
- def unpack_list_of_float_items(self, cdata):
+ def unpack_list_of_float_items(self, ptr, length):
return None
def pack_list_of_items(self, cdata, w_ob):
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
@@ -87,6 +87,13 @@
return self.space.wrap(s)
return W_CType.string(self, cdataobj, maxlen)
+ def unpack_ptr(self, w_ctypeptr, ptr, length):
+ result = self.unpack_list_of_int_items(ptr, length)
+ if result is not None:
+ return self.space.newlist_int(result)
+ return W_CType.unpack_ptr(self, w_ctypeptr, ptr, length)
+
+
class W_CTypePrimitiveCharOrUniChar(W_CTypePrimitive):
_attrs_ = []
is_primitive_integer = True
@@ -229,19 +236,16 @@
def write_raw_integer_data(self, w_cdata, value):
w_cdata.write_raw_signed_data(value)
- def unpack_list_of_int_items(self, w_cdata):
+ def unpack_list_of_int_items(self, ptr, length):
if self.size == rffi.sizeof(rffi.LONG):
from rpython.rlib.rrawarray import populate_list_from_raw_array
res = []
- length = w_cdata.get_array_length()
- with w_cdata as ptr:
- buf = rffi.cast(rffi.LONGP, ptr)
- populate_list_from_raw_array(res, buf, length)
+ buf = rffi.cast(rffi.LONGP, ptr)
+ populate_list_from_raw_array(res, buf, length)
return res
elif self.value_smaller_than_long:
- res = [0] * w_cdata.get_array_length()
- with w_cdata as ptr:
- misc.unpack_list_from_raw_array(res, ptr, self.size)
+ res = [0] * length
+ misc.unpack_list_from_raw_array(res, ptr, self.size)
return res
return None
@@ -321,11 +325,10 @@
def write_raw_integer_data(self, w_cdata, value):
w_cdata.write_raw_unsigned_data(value)
- def unpack_list_of_int_items(self, w_cdata):
+ def unpack_list_of_int_items(self, ptr, length):
if self.value_fits_long:
- res = [0] * w_cdata.get_array_length()
- with w_cdata as ptr:
- misc.unpack_unsigned_list_from_raw_array(res, ptr, self.size)
+ res = [0] * length
+ misc.unpack_unsigned_list_from_raw_array(res, ptr, self.size)
return res
return None
@@ -399,19 +402,16 @@
value = space.float_w(space.float(w_ob))
misc.write_raw_float_data(cdata, value, self.size)
- def unpack_list_of_float_items(self, w_cdata):
+ def unpack_list_of_float_items(self, ptr, length):
if self.size == rffi.sizeof(rffi.DOUBLE):
from rpython.rlib.rrawarray import populate_list_from_raw_array
res = []
- length = w_cdata.get_array_length()
- with w_cdata as ptr:
- buf = rffi.cast(rffi.DOUBLEP, ptr)
- populate_list_from_raw_array(res, buf, length)
+ buf = rffi.cast(rffi.DOUBLEP, ptr)
+ populate_list_from_raw_array(res, buf, length)
return res
elif self.size == rffi.sizeof(rffi.FLOAT):
- res = [0.0] * w_cdata.get_array_length()
- with w_cdata as ptr:
- misc.unpack_cfloat_list_from_raw_array(res, ptr)
+ res = [0.0] * length
+ misc.unpack_cfloat_list_from_raw_array(res, ptr)
return res
return None
@@ -429,6 +429,12 @@
return True
return W_CTypePrimitive.pack_list_of_items(self, cdata, w_ob)
+ def unpack_ptr(self, w_ctypeptr, ptr, length):
+ result = self.unpack_list_of_float_items(ptr, length)
+ if result is not None:
+ return self.space.newlist_float(result)
+ return W_CType.unpack_ptr(self, w_ctypeptr, ptr, length)
+
class W_CTypePrimitiveLongDouble(W_CTypePrimitiveFloat):
_attrs_ = []
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
@@ -206,6 +206,12 @@
storage = strategy.erase(list_i)
return W_ListObject.from_storage_and_strategy(space, storage, strategy)
+ @staticmethod
+ def newlist_float(space, list_f):
+ strategy = space.fromcache(FloatListStrategy)
+ storage = strategy.erase(list_f)
+ return W_ListObject.from_storage_and_strategy(space, storage, strategy)
+
def __repr__(self):
""" representation for debugging purposes """
return "%s(%s, %s)" % (self.__class__.__name__, self.strategy,
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
@@ -294,6 +294,9 @@
def newlist_int(self, list_i):
return W_ListObject.newlist_int(self, list_i)
+ def newlist_float(self, list_f):
+ return W_ListObject.newlist_float(self, list_f)
+
def newdict(self, module=False, instance=False, kwargs=False,
strdict=False):
return W_DictMultiObject.allocate_and_init_instance(
More information about the pypy-commit
mailing list