martes, 9 de febrero de 2021

10) Acelerando expresiones complejas con Numexpr





 Acelerando expresiones complejas con Numexpr


Como vimos en el post anterior, el evaluar expresiones complejas con matrices muy grandes en Numpy hace que el rendimiento del programa decaiga considerablemente.

Por un lado, si usamos una sola línea para evaluar la expresión se producirá un uso alto e ineficiente de la memoria del equipo ya que se crearán unas cuantas matrices temporales que Numpy necesita para evaluar la expresión.

Por otra parte si evaluamos la expresión realizando una operación cada vez, aunque mejor opción que la anterior, nos puede conducir a un rendimiento poco óptimo ya que se utilizarán numerosos bucles "for" del código C de Numpy. 

Para evaluar expresiones que utilicen matrices de una mejor forma podemos usar el paquete numexpr, el cual nos proporciona herramientas para evaluar de una forma rápida expresiones con matrices.

Lo primero de todo es instalar el paquete, ya que no viene por defecto en la instalación de Numpy:

>>> pip3 install numexpr


y luego podemos ver como funciona con el siguiente ejemplo.


>>> import numpy as np

# Creamos 2 matrices x e y con un millón de elementos
>>> x = np.random.random((1_000_000, 1))
>>> y = np.random.random((1_000_000, 1))

>>> import numexpr

# Calculamos la expresión ((.35*x + .85)*x - 1.6)*y - 3
>>> expresion_evaluar = numexpr.evaluate("((.35*x + .85)*x - 1.6)*y - 3") >>> print(expresion_evaluar) [[-4.15069108] [-3.09721302] [-3.14479008] ... [-3.22412767] [-4.28999688] [-3.76542973]]


La expresión se pone entre comillas y se evaluará mediante un solo bucle C. El incremento de velocidad, comparándolo con evaluar la misma expresión solo con Numpy, suele estar entre 0,95 y 4 veces más rápido. El rendimiento suele ser mayor con matrices que no caben en la memoria cache de la CPU.


Los operadores y funciones compatibles que puedes utilizar son:

+, -, *, /, **

sin, cos, tan

exp, log, sqrt









No hay comentarios:

Publicar un comentario