Commit 60cd8333 authored by Stefan Behnel's avatar Stefan Behnel

use slightly faster PyObject_Malloc() instead of PyMem_Malloc() for small...

use slightly faster PyObject_Malloc() instead of PyMem_Malloc() for small memory allocation needs (<= 512 bytes)
parent a2bec15e
...@@ -52,7 +52,7 @@ from libc.string cimport strcat, strncat, \ ...@@ -52,7 +52,7 @@ from libc.string cimport strcat, strncat, \
from cpython.object cimport Py_SIZE from cpython.object cimport Py_SIZE
from cpython.ref cimport PyTypeObject, Py_TYPE from cpython.ref cimport PyTypeObject, Py_TYPE
from cpython.exc cimport PyErr_BadArgument from cpython.exc cimport PyErr_BadArgument
from cpython.mem cimport PyMem_Malloc, PyMem_Free from cpython.mem cimport PyObject_Malloc, PyObject_Free
cdef extern from *: # Hard-coded utility code hack. cdef extern from *: # Hard-coded utility code hack.
ctypedef class array.array [object arrayobject] ctypedef class array.array [object arrayobject]
...@@ -102,7 +102,7 @@ cdef extern from *: # Hard-coded utility code hack. ...@@ -102,7 +102,7 @@ cdef extern from *: # Hard-coded utility code hack.
info.itemsize = self.ob_descr.itemsize # e.g. sizeof(float) info.itemsize = self.ob_descr.itemsize # e.g. sizeof(float)
info.len = info.itemsize * item_count info.len = info.itemsize * item_count
info.shape = <Py_ssize_t*> PyMem_Malloc(sizeof(Py_ssize_t) + 2) info.shape = <Py_ssize_t*> PyObject_Malloc(sizeof(Py_ssize_t) + 2)
if not info.shape: if not info.shape:
raise MemoryError() raise MemoryError()
info.shape[0] = item_count # constant regardless of resizing info.shape[0] = item_count # constant regardless of resizing
...@@ -114,7 +114,7 @@ cdef extern from *: # Hard-coded utility code hack. ...@@ -114,7 +114,7 @@ cdef extern from *: # Hard-coded utility code hack.
info.obj = self info.obj = self
def __releasebuffer__(self, Py_buffer* info): def __releasebuffer__(self, Py_buffer* info):
PyMem_Free(info.shape) PyObject_Free(info.shape)
array newarrayobject(PyTypeObject* type, Py_ssize_t size, arraydescr *descr) array newarrayobject(PyTypeObject* type, Py_ssize_t size, arraydescr *descr)
......
...@@ -73,3 +73,36 @@ cdef extern from "Python.h": ...@@ -73,3 +73,36 @@ cdef extern from "Python.h":
# PyMem_MALLOC(), PyMem_REALLOC(), PyMem_FREE(). # PyMem_MALLOC(), PyMem_REALLOC(), PyMem_FREE().
# PyMem_NEW(), PyMem_RESIZE(), PyMem_DEL(). # PyMem_NEW(), PyMem_RESIZE(), PyMem_DEL().
#####################################################################
# Raw object memory interface
#####################################################################
# Functions to call the same malloc/realloc/free as used by Python's
# object allocator. If WITH_PYMALLOC is enabled, these may differ from
# the platform malloc/realloc/free. The Python object allocator is
# designed for fast, cache-conscious allocation of many "small" objects,
# and with low hidden memory overhead.
#
# PyObject_Malloc(0) returns a unique non-NULL pointer if possible.
#
# PyObject_Realloc(NULL, n) acts like PyObject_Malloc(n).
# PyObject_Realloc(p != NULL, 0) does not return NULL, or free the memory
# at p.
#
# Returned pointers must be checked for NULL explicitly; no action is
# performed on failure other than to return NULL (no warning it printed, no
# exception is set, etc).
#
# For allocating objects, use PyObject_{New, NewVar} instead whenever
# possible. The PyObject_{Malloc, Realloc, Free} family is exposed
# so that you can exploit Python's small-block allocator for non-object
# uses. If you must use these routines to allocate object memory, make sure
# the object gets initialized via PyObject_{Init, InitVar} after obtaining
# the raw memory.
void* PyObject_Malloc(size_t size)
void* PyObject_Calloc(size_t nelem, size_t elsize)
void* PyObject_Realloc(void *ptr, size_t new_size)
void PyObject_Free(void *ptr)
...@@ -498,7 +498,7 @@ __Pyx_CyFunction_clear(__pyx_CyFunctionObject *m) ...@@ -498,7 +498,7 @@ __Pyx_CyFunction_clear(__pyx_CyFunctionObject *m)
for (i = 0; i < m->defaults_pyobjects; i++) for (i = 0; i < m->defaults_pyobjects; i++)
Py_XDECREF(pydefaults[i]); Py_XDECREF(pydefaults[i]);
PyMem_Free(m->defaults); PyObject_Free(m->defaults);
m->defaults = NULL; m->defaults = NULL;
} }
...@@ -708,7 +708,7 @@ static int __pyx_CyFunction_init(void) { ...@@ -708,7 +708,7 @@ static int __pyx_CyFunction_init(void) {
static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *func, size_t size, int pyobjects) { static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *func, size_t size, int pyobjects) {
__pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
m->defaults = PyMem_Malloc(size); m->defaults = PyObject_Malloc(size);
if (!m->defaults) if (!m->defaults)
return PyErr_NoMemory(); return PyErr_NoMemory();
memset(m->defaults, 0, size); memset(m->defaults, 0, size);
......
...@@ -33,6 +33,8 @@ cdef extern from *: ...@@ -33,6 +33,8 @@ cdef extern from *:
void* PyMem_Malloc(size_t n) void* PyMem_Malloc(size_t n)
void PyMem_Free(void *p) void PyMem_Free(void *p)
void* PyObject_Malloc(size_t n)
void PyObject_Free(void *p)
cdef struct __pyx_memoryview "__pyx_memoryview_obj": cdef struct __pyx_memoryview "__pyx_memoryview_obj":
Py_buffer view Py_buffer view
...@@ -137,7 +139,7 @@ cdef class array: ...@@ -137,7 +139,7 @@ cdef class array:
self.format = self._format self.format = self._format
# use single malloc() for both shape and strides # use single malloc() for both shape and strides
self._shape = <Py_ssize_t *> PyMem_Malloc(sizeof(Py_ssize_t)*self.ndim*2) self._shape = <Py_ssize_t *> PyObject_Malloc(sizeof(Py_ssize_t)*self.ndim*2)
self._strides = self._shape + self.ndim self._strides = self._shape + self.ndim
if not self._shape: if not self._shape:
...@@ -212,7 +214,7 @@ cdef class array: ...@@ -212,7 +214,7 @@ cdef class array:
refcount_objects_in_slice(self.data, self._shape, refcount_objects_in_slice(self.data, self._shape,
self._strides, self.ndim, False) self._strides, self.ndim, False)
free(self.data) free(self.data)
PyMem_Free(self._shape) PyObject_Free(self._shape)
property memview: property memview:
@cname('get_memview') @cname('get_memview')
......
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