Un poco de cython





Conseguimos Cythona, gracias al autoaislamiento. El problema es prosaico: cómo acelerar en Python con una mínima pérdida de sintaxis. Un enfoque es usar Cython (una mezcla de C y python).



La publicación con un título sonoro embrujada . Pero poco se puede aprender del contenido de la publicación, ya que las fórmulas y la tabla resultante son incorrectas. Intentemos complementar la imagen iniciada por los autores de la publicación y poner puntos en y.



* Las pruebas se llevaron a cabo en odroid xu4, ubuntu mate, python 2.7.17.

Cython es fácil de instalar (pip install cython).



Torturaremos todos los mismos números de Fibonacci. Creemos archivos para pruebas de aumento de rendimiento. Para el lenguaje Python (test.py):



def test(n):
   a, b = 0.0, 1.0
   for i in range(n):
      a, b = a + b, a
   print (a)


Para el lenguaje cython (test2.pyx):



def test2(int n):
   cdef int i
   cdef double a=0.0, b=1.0
   for i in range(n):
      a, b = a + b, a
   print (a)


El archivo cython requiere compilación previa. Creemos un setup.py para él con el siguiente contenido:



from distutils.core import setup
from Cython.Build import cythonize
setup(ext_modules=cythonize('test2.pyx'))


Y recoger:



python setup.py build_ext --inplace


Ahora tomemos el archivo de la publicación mencionada con pruebas y corrigamos un poco agregando la capacidad de ingresar su propio número al principio (tests.py):



import test
import test2
import time

number = input('enter number: ')

start = time.time()
test.test(number)
end =  time.time()

py_time = end - start
print("Python time = {}".format(py_time))

start = time.time()
test2.test(number)
end =  time.time()

cy_time = end - start
print("Cython time = {}".format(cy_time))
print("Speedup = {}".format(py_time / cy_time))


Vamos a ver que pasó:



python tests.py


Resultados:



para python 2.7:

enter number: 10
Python time = 1.62124633789e-05
Cython time = 4.05311584473e-06
Speedup = 4.0

enter number: 100
Python time = 3.40938568115e-05
Cython time = 5.00679016113e-06
Speedup = 6.80952380952

enter number: 1000
Python time = 0.000224113464355
Cython time = 1.19209289551e-05
Speedup = 18.8

enter number: 100000
Python time = 0.0200171470642
Cython time = 0.000855922698975
Speedup = 23.3866295265




Para Python 3:



enter number: 10
Python time = 7.653236389160156e-05
Cython time = 2.8133392333984375e-05
Speedup = 2.7203389830508473

enter number: 100
Python time = 8.678436279296875e-05
Cython time = 3.170967102050781e-05
Speedup = 2.736842105263158

enter number: 1000
Python time = 0.00031876564025878906
Cython time = 4.673004150390625e-05
Speedup = 6.821428571428571

enter number: 100000
Python time = 0.01643967628479004
Cython time = 0.0004260540008544922
Speedup = 38.5858981533296




* el módulo test2.pyx fue "reconstruido" con el comando:

python3 setup.py build_ext --inplace

** instalado por cython:

pip3 install cython



Puedes hacerlo sin construir test2.pyx usando setup.py, para esto solo necesitas agregar las líneas al archivo tests.py :



import pyximport
pyximport.install()


Ahora test2.pyx se construirá sobre la marcha cada vez que se ejecute tests.py, y habrá menos archivos en la carpeta.



Cómo obtener cython en Windows.



A pesar de que cython permite ensamblar archivos tanto para python3 como para python2, no fue posible obtener una receta preparada para python3 .

Con python3, el comando de compilación funciona:

python setup.py build_ext -i --compiler=msvc


Sin embargo, para su trabajo completo, debe instalar parte de los componentes de Visual Studio 2019. Lo que se debe instalar se indica en la solución aquí .



Por lo tanto, existen dos opciones de trabajo que le permiten trabajar (construir un archivo) en Windows con cython.



El primero usa python2.7 y el compilador mingw.

El procedimiento es el siguiente.

1.Instale cython en python2.7:

py -2 -m pip install cython


2. Instale el compilador mingw:

mingw

3. Después de instalar el compilador y agregarlo a las ventanas PATH, el archivo .pyx se puede compilar con el comando:

python setup.py build_ext -i --compiler=mingw32


El segundo es usar python3.xy el compilador msvc.



Cómo ejecutar cython en un cuaderno jupyter.



A veces es necesario probar visualmente el trabajo del código usando jupyter. Para no compilar el código en cmd cada vez, puede usar cython directamente en las celdas de jupyter.

Para hacer esto, importe cython ejecutando en la celda jupyter:

%load_ext cython


Y ejecutemos algo de código en la siguiente celda:

%%cython -a
import numpy as np

cdef int max(int a, int b):
    return a if a > b else b

cdef int chebyshev(int x1, int y1, int x2, int y2):
    return max(abs(x1 - x2), abs(y1 - y2))

def c_benchmark():
    a = np.random.rand(1000, 2)
    b = np.random.rand(1000, 2)
    
    for x1, y1 in a:
        for x2, y2 in b:
            chebyshev(x1, x2, y1, y2)


Si todo tiene éxito, la salida será así:




All Articles