【发布时间】:2016-01-04 11:53:34
【问题描述】:
我正在编译一个 Cython 模块,并使用 cython -a 命令检查了这段代码。
cdef INT_t print_info(Charge[:] electrons):
cdef INT_t i, index
for i in range(electrons.shape[0]):
index = electrons[i].particleindex
return index
原来是这样的
+ index = electrons[i].particleindex
__pyx_t_4 = __pyx_v_i;
__pyx_t_3 = (PyObject *) *((struct __pyx_obj_14particle_class_Charge * *) ( /* dim=0 */ (__pyx_v_electrons.data + __pyx_t_4 * __pyx_v_electrons.strides[0]) ));
__Pyx_INCREF((PyObject*)__pyx_t_3);
__pyx_t_5 = ((struct __pyx_obj_14particle_class_Charge *)__pyx_t_3)->particleindex;
__Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
__pyx_v_index = __pyx_t_5;
Charge 是一个 cdef 扩展类型,我在这里尝试使用 memoryview 缓冲区Charge[:]。在这种情况下,Cython 似乎调用了一些 Python API,特别是已生成 __Pyx_INCREF((PyObject*) 和 __Pyx_DECREF(((PyObject *)。
我想知道是什么原因造成的,它会导致很多减速吗?这是我在论坛的第一篇文章,非常感谢任何cmets或建议!
PS:Charge对象定义为
charge.pyx
cdef class Charge:
def __cinit__(Charge self):
self.particleindex = 0
self.charge = 0
self.mass = 0
self.energy = 0
self.on_electrode = False
charge.pxd
cdef class Charge:
cdef INT_t particleindex
cdef FLOAT_t charge
cdef FLOAT_t mass
cdef FLOAT_t energy
cdef bint on_electrode
【问题讨论】:
-
INCREF,DECREF- 增加/减少参考(计数)。这是跟踪对 Python 对象的引用(用于垃圾收集)的一部分。_pyx_t_3是类Charge的新(临时)对象,由索引创建。 -
我建议显示定义
Charge的代码。 -
感谢您对我的主题的回复和编辑。定义有什么问题吗?
-
因此,通过索引
electrons[i],您正在创建对Charge对象的临时引用。这就是INCREF的注释。一旦partaicleindex被“存储”在pyx_t_5中,它就会将_pyx_t_3扔掉,并减少引用计数。INCREF/DEC只是普通的 Python 簿记。 -
感谢您的解释。这个过程对代码的速度有任何惩罚吗?如果是这样,有没有办法克服它?
标签: cython