Skip to content

Commit 8f84875

Browse files
committed
MNT: add PyArrayMethodObject caches to static data struct
1 parent 398f095 commit 8f84875

File tree

2 files changed

+57
-54
lines changed

2 files changed

+57
-54
lines changed

numpy/_core/src/multiarray/convert_datatype.c

Lines changed: 48 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -3236,20 +3236,11 @@ nonstructured_to_structured_get_loop(
32363236
return 0;
32373237
}
32383238

3239-
// these are filled in during module initialization
3240-
// we do not include these in the global data struct
3241-
// to avoid the need to #include array_method.h for
3242-
// all users of the global data struct
3243-
static PyArrayMethodObject *VoidToGenericMethod = NULL;
3244-
static PyArrayMethodObject *GenericToVoidMethod = NULL;
3245-
static PyArrayMethodObject *ObjectToGenericMethod = NULL;
3246-
static PyArrayMethodObject *GenericToObjectMethod = NULL;
3247-
32483239
static PyObject *
32493240
PyArray_GetGenericToVoidCastingImpl(void)
32503241
{
3251-
Py_INCREF(GenericToVoidMethod);
3252-
return (PyObject *)GenericToVoidMethod;
3242+
Py_INCREF(npy_ma_static_data->GenericToVoidMethod);
3243+
return npy_ma_static_data->GenericToVoidMethod;
32533244
}
32543245

32553246

@@ -3386,8 +3377,8 @@ structured_to_nonstructured_get_loop(
33863377
static PyObject *
33873378
PyArray_GetVoidToGenericCastingImpl(void)
33883379
{
3389-
Py_INCREF(VoidToGenericMethod);
3390-
return (PyObject *)VoidToGenericMethod;
3380+
Py_INCREF(npy_ma_static_data->VoidToGenericMethod);
3381+
return npy_ma_static_data->VoidToGenericMethod;
33913382
}
33923383

33933384

@@ -3751,8 +3742,8 @@ object_to_any_resolve_descriptors(
37513742
static PyObject *
37523743
PyArray_GetObjectToGenericCastingImpl(void)
37533744
{
3754-
Py_INCREF(ObjectToGenericMethod);
3755-
return (PyObject *)ObjectToGenericMethod;
3745+
Py_INCREF(npy_ma_static_data->ObjectToGenericMethod);
3746+
return npy_ma_static_data->ObjectToGenericMethod;
37563747
}
37573748

37583749

@@ -3788,8 +3779,8 @@ any_to_object_resolve_descriptors(
37883779
static PyObject *
37893780
PyArray_GetGenericToObjectCastingImpl(void)
37903781
{
3791-
Py_INCREF(GenericToObjectMethod);
3792-
return (PyObject *)GenericToObjectMethod;
3782+
Py_INCREF(npy_ma_static_data->GenericToObjectMethod);
3783+
return npy_ma_static_data->GenericToObjectMethod;
37933784
}
37943785

37953786

@@ -3843,62 +3834,65 @@ PyArray_InitializeObjectToObjectCast(void)
38433834

38443835
static int
38453836
initialize_void_and_object_globals(void) {
3846-
VoidToGenericMethod = PyObject_New(PyArrayMethodObject, &PyArrayMethod_Type);
3847-
3848-
if (VoidToGenericMethod == NULL) {
3837+
PyArrayMethodObject *method = PyObject_New(PyArrayMethodObject, &PyArrayMethod_Type);
3838+
if (method == NULL) {
38493839
PyErr_NoMemory();
38503840
return -1;
38513841
}
38523842

3853-
VoidToGenericMethod->name = "void_to_any_cast";
3854-
VoidToGenericMethod->flags = NPY_METH_SUPPORTS_UNALIGNED | NPY_METH_REQUIRES_PYAPI;
3855-
VoidToGenericMethod->casting = -1;
3856-
VoidToGenericMethod->resolve_descriptors = &structured_to_nonstructured_resolve_descriptors;
3857-
VoidToGenericMethod->get_strided_loop = &structured_to_nonstructured_get_loop;
3858-
VoidToGenericMethod->nin = 1;
3859-
VoidToGenericMethod->nout = 1;
3843+
method->name = "void_to_any_cast";
3844+
method->flags = NPY_METH_SUPPORTS_UNALIGNED | NPY_METH_REQUIRES_PYAPI;
3845+
method->casting = -1;
3846+
method->resolve_descriptors = &structured_to_nonstructured_resolve_descriptors;
3847+
method->get_strided_loop = &structured_to_nonstructured_get_loop;
3848+
method->nin = 1;
3849+
method->nout = 1;
3850+
npy_ma_static_data->VoidToGenericMethod = (PyObject *)method;
38603851

3861-
GenericToVoidMethod = PyObject_New(PyArrayMethodObject, &PyArrayMethod_Type);
3862-
if (GenericToVoidMethod == NULL) {
3852+
method = PyObject_New(PyArrayMethodObject, &PyArrayMethod_Type);
3853+
if (method == NULL) {
38633854
PyErr_NoMemory();
38643855
return -1;
38653856
}
38663857

3867-
GenericToVoidMethod->name = "any_to_void_cast";
3868-
GenericToVoidMethod->flags = NPY_METH_SUPPORTS_UNALIGNED | NPY_METH_REQUIRES_PYAPI;
3869-
GenericToVoidMethod->casting = -1;
3870-
GenericToVoidMethod->resolve_descriptors = &nonstructured_to_structured_resolve_descriptors;
3871-
GenericToVoidMethod->get_strided_loop = &nonstructured_to_structured_get_loop;
3872-
GenericToVoidMethod->nin = 1;
3873-
GenericToVoidMethod->nout = 1;
3858+
method->name = "any_to_void_cast";
3859+
method->flags = NPY_METH_SUPPORTS_UNALIGNED | NPY_METH_REQUIRES_PYAPI;
3860+
method->casting = -1;
3861+
method->resolve_descriptors = &nonstructured_to_structured_resolve_descriptors;
3862+
method->get_strided_loop = &nonstructured_to_structured_get_loop;
3863+
method->nin = 1;
3864+
method->nout = 1;
3865+
npy_ma_static_data->GenericToVoidMethod = (PyObject *)method;
38743866

3875-
ObjectToGenericMethod = PyObject_New(PyArrayMethodObject, &PyArrayMethod_Type);
3876-
if (ObjectToGenericMethod == NULL) {
3867+
method = PyObject_New(PyArrayMethodObject, &PyArrayMethod_Type);
3868+
if (method == NULL) {
38773869
PyErr_NoMemory();
38783870
return -1;
38793871
}
38803872

3881-
ObjectToGenericMethod->nin = 1;
3882-
ObjectToGenericMethod->nout = 1;
3883-
ObjectToGenericMethod->name = "object_to_any_cast";
3884-
ObjectToGenericMethod->flags = NPY_METH_SUPPORTS_UNALIGNED | NPY_METH_REQUIRES_PYAPI;
3885-
ObjectToGenericMethod->casting = NPY_UNSAFE_CASTING;
3886-
ObjectToGenericMethod->resolve_descriptors = &object_to_any_resolve_descriptors;
3887-
ObjectToGenericMethod->get_strided_loop = &object_to_any_get_loop;
3873+
method->nin = 1;
3874+
method->nout = 1;
3875+
method->name = "object_to_any_cast";
3876+
method->flags = NPY_METH_SUPPORTS_UNALIGNED | NPY_METH_REQUIRES_PYAPI;
3877+
method->casting = NPY_UNSAFE_CASTING;
3878+
method->resolve_descriptors = &object_to_any_resolve_descriptors;
3879+
method->get_strided_loop = &object_to_any_get_loop;
3880+
npy_ma_static_data->ObjectToGenericMethod = (PyObject *)method;
38883881

3889-
GenericToObjectMethod = PyObject_New(PyArrayMethodObject, &PyArrayMethod_Type);
3890-
if (GenericToObjectMethod == NULL) {
3882+
method = PyObject_New(PyArrayMethodObject, &PyArrayMethod_Type);
3883+
if (method == NULL) {
38913884
PyErr_NoMemory();
38923885
return -1;
38933886
}
38943887

3895-
GenericToObjectMethod->nin = 1;
3896-
GenericToObjectMethod->nout = 1;
3897-
GenericToObjectMethod->name = "any_to_object_cast";
3898-
GenericToObjectMethod->flags = NPY_METH_SUPPORTS_UNALIGNED | NPY_METH_REQUIRES_PYAPI;
3899-
GenericToObjectMethod->casting = NPY_SAFE_CASTING;
3900-
GenericToObjectMethod->resolve_descriptors = &any_to_object_resolve_descriptors;
3901-
GenericToObjectMethod->get_strided_loop = &any_to_object_get_loop;
3888+
method->nin = 1;
3889+
method->nout = 1;
3890+
method->name = "any_to_object_cast";
3891+
method->flags = NPY_METH_SUPPORTS_UNALIGNED | NPY_METH_REQUIRES_PYAPI;
3892+
method->casting = NPY_SAFE_CASTING;
3893+
method->resolve_descriptors = &any_to_object_resolve_descriptors;
3894+
method->get_strided_loop = &any_to_object_get_loop;
3895+
npy_ma_static_data->GenericToObjectMethod = (PyObject *)method;
39023896

39033897
return 0;
39043898
}

numpy/_core/src/multiarray/multiarraymodule.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,15 @@ typedef struct npy_ma_static_data_struct {
128128
* The smallest type number is ?, the largest is bounded by 'z'.
129129
*/
130130
npy_int16 _letter_to_num['z' + 1 - '?'];
131+
132+
/*
133+
* references to ArrayMethod implementations that are cached
134+
* to avoid repeatedly creating them
135+
*/
136+
PyObject *VoidToGenericMethod;
137+
PyObject *GenericToVoidMethod;
138+
PyObject *ObjectToGenericMethod;
139+
PyObject *GenericToObjectMethod;
131140
} npy_ma_static_data_struct;
132141

133142

0 commit comments

Comments
 (0)