Operaciones de arrays de alto rendimiento con Cython | conjunto 2

Requisito previo: operaciones de array de alto rendimiento con Cython | Conjunto 1
El código resultante en la primera parte funciona rápido. En este artículo, compararemos el rendimiento del código con la función clip() que está presente en la biblioteca NumPy. 
En cuanto a la sorpresa, nuestro programa funciona rápido en comparación con el NumPy que está escrito en C.
Código #1: Comparando las actuaciones. 
 

Python3

a = timeit('numpy.clip(arr2, -5, 5, arr3)',
       'from __main__ import b, c, numpy', number = 1000)
 
print ("\nTime for NumPy clip program : ", a)
 
b = timeit('sample.clip(arr2, -5, 5, arr3)',
           'from __main__ import b, c, sample', number = 1000)
 
print ("\nTime for our program : ", b)

Producción : 
 

Time for NumPy clip program : 8.093049556000551

Time for our program :, 3.760528204000366

Bueno, los códigos en el artículo requerían vistas de memoria tipeadas por Cython que simplifican el código que opera en arrays. La declaración cpdef clip() declara clip() como una función de nivel C y Python. Esto significa que la llamada de función es llamada de manera más eficiente por otras funciones de Cython (por ejemplo, si desea invocar clip() desde una función de Cython diferente).
Se utilizan dos decoradores en el código: @cython.boundscheck(False) y @cython.wraparound(False) . Tales son las pocas optimizaciones de rendimiento opcionales. 
@cython.boundscheck(False): elimina todas las comprobaciones de los límites de la array y se puede usar si la indexación no se sale del rango. 
@cython.wraparound(Falso) :Elimina el manejo de índices de array negativos como si se envolvieran hasta el final de la array (como con las listas de Python). La inclusión de estos decoradores puede hacer que el código se ejecute mucho más rápido (casi 2,5 veces más rápido en este ejemplo cuando se prueba).
Código #2: Variante de la función clip() que usa expresiones condicionales 
 

Python3

# decorators
@cython.boundscheck(False)
@cython.wraparound(False)
 
cpdef clip(double[:] a, double min, double max, double[:] out):
     
    if min > max:
        raise ValueError("min must be <= max")
     
    if a.shape[0] != out.shape[0]:
        raise ValueError
        ("input and output arrays must be the same size")
     
    for i in range(a.shape[0]):
        out[i] = (a[i]
        if a[i] < max else max)
        if a[i] > min else min

Cuando se prueba, esta versión del código se ejecuta un 50 % más rápido. Pero, ¿cómo se compararía este código con una versión C escrita a mano? Después de experimentar, se puede probar que una extensión C hecha a mano se ejecuta más de un 10% más lento que la versión creada por Cython.
 

Publicación traducida automáticamente

Artículo escrito por manikachandna97 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *