Repository: numpy/numpy
File: numpy/_core/src/multiarray/methods.c (C)

Code before:
        order = 'K';
        const int n = PyArray_NDIM(self);
        npy_stride_sort_item items[NPY_MAXDIMS];
        // sort (strde, perm) as descending = transpose to C
        PyArray_CreateSortedStridePerm(n, PyArray_STRIDES(self), items);
        rev_perm = PyTuple_New(n);
        if(rev_perm == NULL) {
            Py_DECREF(picklebuf_class);
            return NULL;
        }
        PyArray_Dims dims;
        npy_intp d[NPY_MAXDIMS];
        for (int i = 0; i < n; i++) {
            d[i] = items[i].perm;
            PyTuple_SET_ITEM(rev_perm, items[i].perm, PyLong_FromLong(i));
        }
        dims.ptr = d;
        dims.len = n;
        transposed_array = PyArray_Transpose((PyArrayObject *)self, &dims);
        if (!PyArray_IS_C_CONTIGUOUS((PyArrayObject *)transposed_array)) {
            // self is non-contiguous
            Py_DECREF(picklebuf_class);
            Py_DECREF(rev_perm);
            return array_reduce_ex_regular(self, protocol);
        }
        picklebuf_args = Py_BuildValue("(N)", transposed_array);
    }
    if (picklebuf_args == NULL) {
        Py_DECREF(picklebuf_class);
        return NULL;
    }

    buffer = PyObject_CallObject(picklebuf_class, picklebuf_args);
    Py_DECREF(picklebuf_class);
    Py_DECREF(picklebuf_args);
    if (buffer == NULL) {
        /* Some arrays may refuse to export a buffer, in which case
         * just fall back on regular __reduce_ex__ implementation
         * (gh-12745).
         */
        PyErr_Clear();
        return array_reduce_ex_regular(self, protocol);
    }

    /* Get the _frombuffer() function for reconstruction */

    numeric_mod = PyImport_ImportModule("numpy._core.numeric");
    if (numeric_mod == NULL) {
        Py_DECREF(buffer);
        return NULL;
    }

Review comment (performance):
Feel free to ignore, `picklebuf_args` is also rather silly as a tuple.  We should just use `PyObject_CallOneArg(transposed_array != NULL ? transposed_array : self)`.
Faster, and no need to fight with `picklebuf_args` cleanup.

Even better: if we cache `picklebuf_class` using the `npy_cache_import_runtime` pattern we also don't need to clean that up.

Code after:
            Py_DECREF(rev_perm);
            return NULL;
        }
        if (!PyArray_IS_C_CONTIGUOUS((PyArrayObject *)transposed_array)) {
            // self is non-contiguous
            Py_DECREF(rev_perm);
            Py_DECREF(transposed_array);
            return array_reduce_ex_regular(self, protocol);
        }
    }
    buffer = PyObject_CallOneArg(picklebuf_class, transposed_array == NULL ? (PyObject*) self: transposed_array);
    if (buffer == NULL) {
        /* Some arrays may refuse to export a buffer, in which case
         * just fall back on regular __reduce_ex__ implementation
         * (gh-12745).
         */
        Py_XDECREF(rev_perm);
        Py_XDECREF(transposed_array);
        PyErr_Clear();
        return array_reduce_ex_regular(self, protocol);
    }

    /* Get the _frombuffer() function for reconstruction */
    if (npy_cache_import_runtime("numpy._core.numeric", "_frombuffer",
                                 &from_buffer_func) == -1) {
        Py_XDECREF(rev_perm);
        Py_XDECREF(transposed_array);
        Py_DECREF(buffer);
        return NULL;
    }

    PyObject *shape = NULL;
    if (order == 'K') {
        shape = PyArray_IntTupleFromIntp(
                PyArray_NDIM((PyArrayObject *)transposed_array),
                PyArray_SHAPE((PyArrayObject *)transposed_array));
    }
    else {
        shape = PyArray_IntTupleFromIntp(PyArray_NDIM(self),
                                         PyArray_SHAPE(self));
    }
    Py_XDECREF(transposed_array);
    if (shape == NULL) {
        Py_XDECREF(rev_perm);
        Py_DECREF(buffer);
        return NULL;
    }
    if (order == 'K') {
        return Py_BuildValue("N(NONNN)", from_buffer_func, buffer,
                             (PyObject *)descr, shape,
                             PyUnicode_FromStringAndSize(&order, 1), rev_perm);