2011-01-17 23 views
7

Tôi đang thực hiện một số tính toán chuyên sâu vòng lặp và chuyển đổi mã thành Cython. tôi đã profiling với tùy chọn -a cython, và kiểm tra các tập tin .html, và có vẻ như bất cứ khi nào tôi làm bộ phận phao, có dòng hơi vàng và nó giống như sau:Phân chia phao Cython PyExc_ZeroDivisionError kiểm tra

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;} 
     } 

Tôi đoán nó là dành cho các trường hợp mà dải phân cách là 0. Tôi đang sử dụng hằng số cho điều đó và không có xác suất nào là dải phân cách là 0, và tôi đã tự hỏi liệu có bất kỳ điều gì tôi có thể làm để làm cho nó nhanh hơn không.

+0

Bạn đã sử dụng 'cdef float yourconstant' (và cho phần khác của bộ phận quá)? Bạn có thể hiển thị một số mã không? – TryPyPy

+0

Hmm, có vẻ như nó thích 'cdef double' tốt hơn. – TryPyPy

Trả lời

13

Bạn cần phải thêm @cython.cdivision(True) để tránh sự kiểm tra ngoại lệ.

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

hoặc bạn có thể sử dụng chỉ thị chung. Xem http://wiki.cython.org/enhancements/compilerdirectives –

+0

Cảm ơn bạn rất nhiều về điều này! – joon

0

Nếu số chia là hằng số, bạn có thể nhân bằng 1/divisor thay

Các vấn đề liên quan