Una parte esencial del modelado de simulación es el tiempo de ejecución de la simulación. Los modelos de simulación de eventos discretos grandes e incluso los modelos de simulación basados en agentes de tamaño mediano consumen recursos computacionales y pueden tener un tiempo de ejecución muy largo. Esto es especialmente cierto si el código fuente está completamente escrito en Python. Por lo tanto, realicé algunas pruebas con Numba en Python. Comparto mis resultados aquí. Primero ejecuto una prueba simple en una función de prueba en Python. Después de eso, resumo mis mejoras en el rendimiento del tiempo de ejecución al aplicar Numba a mi marco de trabajo de modelado basado en agentes en Python.
Instalar Numba en Python
Numba se puede instalar usando el comando pip install. Simplemente escriba lo siguiente en su terminal:
pip install numba
Para las listas, le recomiendo que use numpy (es decir , matrices numpy ), ya que esto le permitirá evitar la lista predeterminada de Python . Si aún no está instalado, puede instalar numy de la misma manera:
pip install numpy
Ahora puede importar numpy y numba y usar numba para hacer que su código se ejecute más rápido. Para esto puedes usar el decorador @njit .
Probando la mejora del rendimiento de Numba en Python
Es hora de echar un vistazo a una prueba simple de mejora del tiempo de ejecución en Python. El siguiente código implementa Numba para tener un programa de Python más rápido.
import numpy as np
from numba import jit
import random
import time
def rand_events(n: int) -> np.ndarray:
ls = np.zeros(n)
for i in range(n):
x = random.random()
while True:
y = random.random()
if x < y:
ls[i] = y
break
return ls
""" RUNTIME TEST WITHOUT NUMBA -------------------------- """
_start_time = time.time()
vals = rand_events(10000000)
_end_time = time.time()
print(str(_end_time - _start_time))
""" RUNTIME TEST WITH NUMBA ------------------------------ """
_start_time = time.time()
jit_rand_events = jit(nopython=True)(rand_events)
vals = jit_rand_events(10000000)
_end_time = time.time()
print(str(_end_time-_start_time))
_start_time = time.time()
vals = jit_rand_events(10000000)
_end_time = time.time()
print(str(_end_time-_start_time))
En el código anterior, llamar a jit(nopython=True) equivale al uso del declarador @njit . Cuando se ejecuta el código anterior, la salida en la terminal será algo similar a lo siguiente (depende de la máquina y el resultado de la generación de números aleatorios)
9.1829195022583 1.2913379669189453 0.8751001358032227
Esto significa que tomó 9.18 segundos llamar a la función rand_events() con n = 10,000,000. Después de aplicar el declarador @njit y ejecutar la función nuevamente, toma solo 1,29 segundos (incluido el «ejecutar» la función). Sin la llamada del declarador @njit , se tardaría 0,87 segundos en llamar a la versión «jitted» de rand_events(). Esa es una mejora significativa en el tiempo de ejecución.
Aplicar Numba para simulaciones de Python más rápidas
Numba puede hacer que los marcos de simulación sean más rápidos. Pero solo si las partes principales del marco están orientadas numéricamente. Además, el marco debe integrar numpy , ya que numba entiende muy bien numpy . En un marco fuertemente orientado a objetos, esto puede ser un desafío. Pero si puede lograr transformar partes del código de uso intensivo de computación en código numérico, entonces numba puede generar mejoras significativas en el tiempo de ejecución del código de Python.
Ingeniero industrial especializado en optimización y simulación (R, Python, SQL, VBA)
Leave a Reply