Skip to content

Commit

Permalink
Optimize cybuffer's method tolist
Browse files Browse the repository at this point in the history
Makes some improvements to `tolist` by rewriting the underlying utility
function to operate directly on the raw pointer to the data instead of
using Cython's `memoryview` object. Overall improves the speed of
`tolist` by 4-fold. Also removes reliance on Cython's `memoryview` type
for the `tolist` method, which saves a fair bit of overhead.
  • Loading branch information
jakirkham committed Nov 20, 2018
1 parent d3cb337 commit e8b2a03
Showing 1 changed file with 14 additions and 14 deletions.
28 changes: 14 additions & 14 deletions src/cybuffer.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ from cpython.buffer cimport (
)

from array import array
from struct import unpack as struct_unpack

IF PY2K:
import binascii
Expand Down Expand Up @@ -75,22 +76,24 @@ cdef tuple pointer_to_tuple(int n, Py_ssize_t* p):
@cython.initializedcheck(False)
@cython.nonecheck(False)
@cython.wraparound(False)
cdef list cvmemoryview_to_list(cvmemoryview mv):
cdef list pointer_to_list(int n, Py_ssize_t* shape, Py_ssize_t* strides,
bytes fmt, Py_ssize_t itemsize, const char* d):
cdef list r
cdef cvmemoryview mv_i
cdef object r_i
cdef Py_ssize_t i, l

l = mv.view.shape[0]
l = shape[0]
r = cpython.list.PyList_New(l)
if mv.view.ndim > 1:
if n > 1:
for i in range(l):
mv_i = mv[i]
r_i = cvmemoryview_to_list(mv_i)
r_i = pointer_to_list(
n - 1, &shape[1], &strides[1],
fmt, itemsize, d + i * strides[0]
)
PyList_SET_ITEM_INC(r, i, r_i)
else:
for i in range(l):
r_i = mv[i]
r_i = struct_unpack(fmt, (d + i * strides[0])[:itemsize])[0]
PyList_SET_ITEM_INC(r, i, r_i)

return r
Expand Down Expand Up @@ -282,13 +285,10 @@ cdef class cybuffer(object):


cpdef list tolist(self):
cdef list r
cdef cvmemoryview mv

mv = cvmemoryview(self, PyBUF_FULL_RO)
r = cvmemoryview_to_list(mv)

return r
return pointer_to_list(
self._buf.ndim, self._shape, self._strides,
self._format, self.itemsize, <const char*>self._buf.buf
)


def __getbuffer__(self, Py_buffer* buf, int flags):
Expand Down

0 comments on commit e8b2a03

Please sign in to comment.