10

我正在做一些循环密集型计算并将代码转换为 Cython。我使用 cython -a 选项进行了分析,并检查了 .html 文件,似乎每当我进行浮点除法时,都会出现一些黄线,它会执行以下操作:

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,我想知道是否有什么办法可以让它更快。

4

2 回答 2

16

您需要添加@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
于 2011-01-17T02:06:21.883 回答
1

1/divisor如果除数是常数,则可以乘以

于 2011-01-17T01:55:25.123 回答