2011-11-10 13 views
8

estoy aprendiendo Cython y encontré este snippit de código:Cython: para i de 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) 

Obviamente, esto devuelve la media de un que es 2,5. Mi pregunta es la siguiente:

¿El bucle for es un bucle Python, Cython o C?

Respuesta

5

Compilar y ver: el código C que Cython produce está muy bien anotado.

/* "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))); 
    } 

Y por lo que el propio bucle se activa con éxito en C. Tenga en cuenta que en estos días Cython puede manejar surtido de forma natural, por lo que el más viejo "de 0 < = i < N" estilo no es necesario. El objetivo de introducir la sintaxis "for/from" (no de Python) era indicar qué bucles deberían C-ified.

+0

Hice algunas pruebas TimeIt ingenuos y dos estructuras de bucle parecen funcionar en aproximadamente la misma cantidad de tiempo con gran tamaño de la matriz. ¿Alguien puede confirmar esto? Solo tengo curiosidad de por qué el autor de este snippit particular eligió usar la estructura anterior en el código moderno. –

+1

En el pasado, Cython no optimizaba 'for i in range (10)', por lo que crearía una lista de longitud 10 e iteraría sobre ella utilizando las llamadas de devolución de Python. Debido a esto, Pyrex/Cython introdujo la sintaxis de ... de ..., que se reduciría a C. A veces sigo usando la sintaxis anterior porque es más claro que este código está optimizado. – carl

Cuestiones relacionadas