2011-11-10 41 views
8

tôi đang học Cython và đã xem qua snippit mã này:Cython: for i từ 1 <= i <N

import numpy as np 
cimport numpy as np 

def mean(np.ndarray[np.double_t] input): 

    cdef np.double_t cur 
    # Py_ssize_t is numpy's index type 
    cdef Py_ssize_t i 
    cdef Py_ssize_t N = len(input) 

    for i from 0 <= i < N: 
     cur += input[i] 

    return cur/N 

a=np.array([1,2,3,4], dtype=np.double) 

Rõ ràng, điều này trả về giá trị trung bình của một đó là 2,5. Câu hỏi của tôi là thế này:

là vòng lặp for một vòng lặp Python, Cython, hay C?

Trả lời

5

Biên dịch nó và xem: mã C Cython sản xuất là độc đáo được chú thích.

/* "cyexample.pyx":11 
*  cdef Py_ssize_t N = len(input) 
* 
*  for i from 0 <= i < N:    # <<<<<<<<<<<<<< 
*   cur += input[i] 
* 
*/ 
    __pyx_t_1 = __pyx_v_N; 
    for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_1; __pyx_v_i++) { 
    /* "cyexample.pyx":12 
* 
*  for i from 0 <= i < N: 
*   cur += input[i]    # <<<<<<<<<<<<<< 
* 
*  return cur/N 
*/ 
    __pyx_t_2 = __pyx_v_i; 
    __pyx_t_3 = -1; 
    if (__pyx_t_2 < 0) { 
     __pyx_t_2 += __pyx_bshape_0_input; 
     if (unlikely(__pyx_t_2 < 0)) __pyx_t_3 = 0; 
    } else if (unlikely(__pyx_t_2 >= __pyx_bshape_0_input)) __pyx_t_3 = 0; 
    if (unlikely(__pyx_t_3 != -1)) { 
     __Pyx_RaiseBufferIndexError(__pyx_t_3); 
     {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 
    } 
    __pyx_v_cur = (__pyx_v_cur + (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_double_t *, __pyx_bstruct_input.buf, __pyx_t_2, __pyx_bstride_0_input))); 
    } 

Và như vậy vòng lặp tự nó được quay thành công vào C. Lưu ý rằng những ngày này Cython có thể xử lý ca nô tự nhiên, do đó cũ "từ 0 < = i < N" phong cách không cần thiết. Điểm giới thiệu cú pháp (không phải Python) "cho/từ" là để biểu thị vòng lặp nào nên là C-ified.

+0

tôi đã làm một số xét nghiệm timeit ngây thơ và cả cấu trúc vòng lặp xuất hiện để chạy trong khoảng cùng một lượng thời gian với kích thước mảng lớn. bất cứ ai có thể xác nhận điều này? Tôi chỉ tò mò tại sao tác giả của đoạn trích cụ thể này lại chọn sử dụng cấu trúc cũ hơn trong mã hiện đại. –

+1

Trở lại trong ngày, Cython sẽ không tối ưu hóa 'for i in range (10) ', vì vậy nó sẽ thực sự tạo ra một danh sách dài 10 và lặp trên nó sử dụng Python lưng gọi. Do đó, Pyrex/Cython đã giới thiệu cú pháp ... từ ..., sẽ đun sôi xuống C. Tôi đôi khi vẫn sử dụng cú pháp cũ hơn vì rõ ràng hơn là mã này được tối ưu hóa. – carl

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