如何遍历ac扩展中的所有python对象?

asc*_*moo 5 python python-c-api python-internals

我正在使用python 内存分析器,我使用以下方法收集python对象的大小:

sum(map(sys.getsizeof, gc.get_objects()))
Run Code Online (Sandbox Code Playgroud)

这是代码中最慢的部分 - 特别是gc.get_objects- 所以我决定加快速度并将其重写为交流扩展.问题是python c API无法访问gc模块所使用的内部数据gc.get_objects.

是否可以使用c API迭代所有对象,而无需调用昂贵的gc.get_objects

小智 0

这是我在 GitHub 上找到的代码

https://github.com/crazyguitar/pysheeet/blob/master/docs/notes/python-c-extensions.rst#iterate-a-list

#include <Python.h>

#define PY_PRINTF(o) \
    PyObject_Print(o, stdout, 0); printf("\n");

static PyObject *
iter_list(PyObject *self, PyObject *args)
{
    PyObject *list = NULL, *item = NULL, *iter = NULL;
    PyObject *result = NULL;

    if (!PyArg_ParseTuple(args, "O", &list))
        goto error;

    if (!PyList_Check(list))
        goto error;

    // Get iterator
    iter = PyObject_GetIter(list);
    if (!iter)
        goto error;

    // for i in arr: print(i)
    while ((item = PyIter_Next(iter)) != NULL) {
        PY_PRINTF(item);
        Py_XDECREF(item);
    }

    Py_XINCREF(Py_None);
    result = Py_None;
error:
    Py_XDECREF(iter);
    return result;
}

static PyMethodDef methods[] = {
    {"iter_list", (PyCFunction)iter_list, METH_VARARGS, NULL},
    {NULL, NULL, 0, NULL}
};

static struct PyModuleDef module = {
    PyModuleDef_HEAD_INIT, "foo", NULL, -1, methods
};

PyMODINIT_FUNC PyInit_foo(void)
{
    return PyModule_Create(&module);
}
Run Code Online (Sandbox Code Playgroud)