Commit ebbab491 authored by Stefan Behnel's avatar Stefan Behnel

Refactor "cython.array" initialisation to avoid a bit of overhead.

parent 2fc95d32
...@@ -124,8 +124,7 @@ cdef class array: ...@@ -124,8 +124,7 @@ cdef class array:
mode="c", bint allocate_buffer=True): mode="c", bint allocate_buffer=True):
cdef int idx cdef int idx
cdef Py_ssize_t i, dim cdef Py_ssize_t dim
cdef PyObject **p
self.ndim = <int> len(shape) self.ndim = <int> len(shape)
self.itemsize = itemsize self.itemsize = itemsize
...@@ -155,32 +154,22 @@ cdef class array: ...@@ -155,32 +154,22 @@ cdef class array:
self._shape[idx] = dim self._shape[idx] = dim
cdef char order cdef char order
if mode == 'fortran': if mode == 'c':
order = b'F'
self.mode = u'fortran'
elif mode == 'c':
order = b'C' order = b'C'
self.mode = u'c' self.mode = u'c'
elif mode == 'fortran':
order = b'F'
self.mode = u'fortran'
else: else:
raise ValueError(f"Invalid mode, expected 'c' or 'fortran', got {mode}") raise ValueError(f"Invalid mode, expected 'c' or 'fortran', got {mode}")
self.len = fill_contig_strides_array(self._shape, self._strides, self.len = fill_contig_strides_array(self._shape, self._strides, itemsize, self.ndim, order)
itemsize, self.ndim, order)
self.free_data = allocate_buffer self.free_data = allocate_buffer
self.dtype_is_object = format == b'O' self.dtype_is_object = format == b'O'
if allocate_buffer:
# use malloc() for backwards compatibility
# in case external code wants to change the data pointer
self.data = <char *>malloc(self.len)
if not self.data:
raise MemoryError("unable to allocate array data.")
if self.dtype_is_object: if allocate_buffer:
p = <PyObject **> self.data _allocate_buffer(self)
for i in range(self.len // itemsize):
p[i] = Py_None
Py_INCREF(Py_None)
@cname('getbuffer') @cname('getbuffer')
def __getbuffer__(self, Py_buffer *info, int flags): def __getbuffer__(self, Py_buffer *info, int flags):
...@@ -212,10 +201,9 @@ cdef class array: ...@@ -212,10 +201,9 @@ cdef class array:
def __dealloc__(array self): def __dealloc__(array self):
if self.callback_free_data != NULL: if self.callback_free_data != NULL:
self.callback_free_data(self.data) self.callback_free_data(self.data)
elif self.free_data: elif self.free_data and self.data is not NULL:
if self.dtype_is_object: if self.dtype_is_object:
refcount_objects_in_slice(self.data, self._shape, refcount_objects_in_slice(self.data, self._shape, self._strides, self.ndim, inc=False)
self._strides, self.ndim, False)
free(self.data) free(self.data)
PyObject_Free(self._shape) PyObject_Free(self._shape)
...@@ -241,16 +229,35 @@ cdef class array: ...@@ -241,16 +229,35 @@ cdef class array:
self.memview[item] = value self.memview[item] = value
@cname("__pyx_array_allocate_buffer")
cdef int _allocate_buffer(array self) except -1:
# use malloc() for backwards compatibility
# in case external code wants to change the data pointer
cdef Py_ssize_t i
cdef PyObject **p
self.free_data = True
self.data = <char *>malloc(self.len)
if not self.data:
raise MemoryError("unable to allocate array data.")
if self.dtype_is_object:
p = <PyObject **> self.data
for i in range(self.len // self.itemsize):
p[i] = Py_None
Py_INCREF(Py_None)
return 0
@cname("__pyx_array_new") @cname("__pyx_array_new")
cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, char *c_mode, char *buf):
char *mode, char *buf):
cdef array result cdef array result
cdef str mode = "fortran" if c_mode[0] == b'f' else "c" # this often comes from a constant C string.
if buf == NULL: if buf is NULL:
result = array(shape, itemsize, format, mode.decode('ASCII')) result = array.__new__(array, shape, itemsize, format, mode)
else: else:
result = array(shape, itemsize, format, mode.decode('ASCII'), result = array.__new__(array, shape, itemsize, format, mode, allocate_buffer=False)
allocate_buffer=False)
result.data = buf result.data = buf
return result return result
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment