如何避免PyObject_to_MemoryviewSlice、GOTREF/DECREF Python API调用?

2024-09-27 17:32:41 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个问题,cythonizing我的代码,更具体地说,以下(和类似的)sniplets:

cdef double [:,:] grad_d_him_d_jm
grad_d_ihm_d_jm = grad_d_im_d_jm(...)

其中grad_d_im_d_jm(…)将返回一个双[:,:]memoryview。 这段代码将由Cython翻译成以下C代码:

^{pr2}$

当我在循环中执行此操作时,我怀疑pythonapi调用对我的代码速度有相当大的影响。在

GOTREF/DECREF调用在其他情况下也会发生,同时会出现PyFloat_asFloat:

cdef float sp
sp = scalar_product()

其中scalar_product()返回cdef浮点。此片段被翻译为

__pyx_t_1 = __pyx_f_24gradient_better_c_mviews_scalar_product(__pyx_v_i, __pyx_v_j, __pyx_v_m, __pyx_v_structure); 
if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_1);
__pyx_t_2 = __pyx_PyFloat_AsFloat(__pyx_t_1); 
if (unlikely((__pyx_t_2 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_v_sp = __pyx_t_2;

我运行的是python2.7.11+和cython0.23.4。如果您能告诉我a)这与性能无关,或者b)如何修复它,我将非常感激。 让我知道如果我能改进这个问题,我很乐意这样做。在


Tags: 代码ifproductfloatspscalarpyxim
1条回答
网友
1楼 · 发布于 2024-09-27 17:32:41

这些似乎是Cython引用计数API解释的here的一部分。在

我的猜测是grad_d_im_d_jm返回一个Python对象(例如NumPy数组),因此Cython必须在获得memoryview之后递减对象引用计数器。在

至于scalar_product,我认为它要么是def(而不是cdef),要么是非类型化的。例如以下内容

cdef g():
    return 1.0

编译到

^{pr2}$

但是,一旦指定了返回类型,refcounting调用就消失了

cdef float g():
    return 1.0

变成

// ...
__pyx_r = 1.0;
goto __pyx_L0;

相关问题 更多 >

    热门问题