8000 ENH: Speed up tolist() by removing intermediate temporary allocations… · numpy/numpy@c7040ba · GitHub
[go: up one dir, main page]

Skip to content

Commit c7040ba

Browse files
committed
ENH: Speed up tolist() by removing intermediate temporary allocations (#1779)
1 parent b126a3f commit c7040ba

File tree

1 file changed

+37
-24
lines changed

1 file changed

+37
-24
lines changed

numpy/core/src/multiarray/convert.c

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,39 +17,52 @@
1717

1818
#include "convert.h"
1919

20-
/*NUMPY_API
21-
* To List
20+
/*
21+
* Converts a subarray of 'self' into lists, with starting data pointer
22+
* 'dataptr' and from dimension 'startdim' to the last dimension of 'self'.
23+
*
24+
* Returns a new reference.
2225
*/
23-
NPY_NO_EXPORT PyObject *
24-
PyArray_ToList(PyArrayObject *self)
26+
static PyObject *
27+
recursive_tolist(PyArrayObject *self, char *dataptr, int startdim)
2528
{
26-
PyObject *lp;
27-
PyArrayObject *v;
28-
intp sz, i;
29+
npy_intp i, n, stride;
30+
PyObject *ret, *item;
2931

30-
if (!PyArray_Check(self)) {
31-
return (PyObject *)self;
32+
/* Base case */
33+
if (startdim >= PyArray_NDIM(self)) {
34+
return PyArray_DESCR(self)->f->getitem(dataptr,self);
3235
}
33-
if (self->nd == 0) {
34-
return self->descr->f->getitem(self->data,self);
36+
37+
n = PyArray_DIM(self, startdim);
38+
stride = PyArray_STRIDE(self, startdim);
39+
40+
ret = PyList_New(n);
41+
if (ret == NULL) {
42+
return NULL;
3543
}
3644

37-
sz = self->dimensions[0];
38-
lp = PyList_New(sz);
39-
for (i = 0; i < sz; i++) {
40-
v = (PyArrayObject *)array_big_item(self, i);
41-
if (PyArray_Check(v) && (v->nd >= self->nd)) {
42-
PyErr_SetString(PyExc_RuntimeError,
43-
"array_item not returning smaller-" \
44-
"dimensional array");
45-
Py_DECREF(v);
46-
Py_DECREF(lp);
45+
for (i = 0; i < n; ++i) {
46+
item = recursive_tolist(self, dataptr, startdim+1);
47+
if (item == NULL) {
48+
Py_DECREF(ret);
4749
return NULL;
4850
}
49-
PyList_SetItem(lp, i, PyArray_ToList(v));
50-
Py_DECREF(v);
51+
PyList_SET_ITEM(ret, i, item);
52+
53+
dataptr += stride;
5154
}
52-
return lp;
55+
56+
return ret;
57+
}
58+
59+
/*NUMPY_API
60+
* To List
61+
*/
62+
NPY_NO_EXPORT PyObject *
63+
PyArray_ToList(PyArrayObject *self)
64+
{
65+
return recursive_tolist(self, PyArray_DATA(self), 0);
5366
}
5467

5568
/* XXX: FIXME --- add ordering argument to

0 commit comments

Comments
 (0)
0