Cython float division PyExc_ZeroDivisionError checking
I'm doing some loop-intensive calculations and converted the code into Cython. I did profiling with cython -a option, and inspected the .html file, and it seems whenever I do the float division, there is somewhat yellow line and it does something like the following:
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;}
}
I guess it is for the cases where the divider is 0. I am using a constant for that and there is no probability that the divider is 0, and I was wondering if there is anything I c开发者_如何学运维an do to make it faster.
You need to add @cython.cdivision(True)
to avoid the exception checking.
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
If the divisor is constant, you can multiply by 1/divisor
instead
精彩评论