2011-01-17 47 views
7

我正在做一些循环密集计算并将代码转换为Cython。 我就与用Cython -a选项分析,并考察了.html文件,似乎每当我做浮动师,有几分黄线和它类似如下:Cython float division PyExc_ZeroDivisionError检查

if (unlikely(__pyx_t_37 == 0)) { 
     PyErr_Format(PyExc_ZeroDivisionError, "float division"); 
     {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 
     } 

我想这适用于分频器为0的情况。我为此使用了一个常数,并且分频器不可能是0,而且我想知道是否有任何事情可以使它更快。

+0

您是否已经在使用'cdef float yourconstant'(以及该部门的其他部分)?你能展示一些代码吗? – TryPyPy

+0

嗯,它看起来更喜欢'cdef double'。 – TryPyPy

回答

13

您需要添加@cython.cdivision(True)避免异常检查。

import cython 

cdef double pydivision(): 
    cdef int i 
    cdef double k, j 
    k = 2.0 
    j = 0.0 
    for i in range(10): 
    j += i/k 
    # Generated code: Python exception checking 
    # /* "checksum.pyx":9 
    # * j = 0.0 
    # * for i in range(10): 
    # *  j += i/k    # <<<<<<<<<<<<<< 
    # * return j 
    # * 
    # */ 
    # if (unlikely(__pyx_v_k == 0)) { 
    #  PyErr_Format(PyExc_ZeroDivisionError, "float division"); 
    #  {__pyx_filename = __pyx_f[0]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 
    # } 
    # __pyx_v_j = (__pyx_v_j + (__pyx_v_i/__pyx_v_k)); 
    # } 
    return j 

#This decorator works wonders 
@cython.cdivision(True) 
cdef double cdivision(): 
    cdef int i 
    cdef double k, j 
    k = 2.0 
    j = 0.0 
    for i in range(10): 
    j += i/k 
    # Generated code: no exception checking 
    # /* "checksum.pyx":20 
    # * j = 0.0 
    # * for i in range(10): 
    # *  j += i/k    # <<<<<<<<<<<<<< 
    # * return j 
    # * 
    # */ 
    # __pyx_v_j = (__pyx_v_j + (__pyx_v_i/__pyx_v_k)); 
    # } 
    return j 
+1

或者您可以使用全局指令。见http://wiki.cython.org/enhancements/compilerdirectives –

+0

非常感谢! – joon

0

如果除数是恒定的,你可以通过1/divisor繁殖,而不是