En væsentlig del af simuleringsmodellering er simuleringskørsel. Store diskrete hændelsessimuleringsmodeller og endda mellemstore agentbaserede simuleringsmodeller bruger beregningsressourcer og kan have en meget lang driftstid. Dette gælder især, hvis kildekoden er fuldt ud skrevet i Python. Jeg gennemførte derfor nogle tests med Numba i Python. Jeg deler mine resultater her. Først kører jeg en simpel test på en testfunktion i Python. Derefter opsummerer jeg mine forbedringer af runtime-ydeevnen fra at have anvendt Numba til min agentbaserede modelleringsramme i Python.
Installation af Numba i Python
Numba kan installeres ved hjælp af kommandoen pip install. Indtast blot følgende i din terminal:
pip install numba
Til lister anbefaler jeg, at du bruger numpy (dvs. numpy arrays), da dette vil tillade dig at undgå standard Python-liste . Hvis det ikke allerede er installeret, kan du installere numy på samme måde:
pip install numpy
Du kan nu importere numpy og numba og bruge numba til at få din kode til at køre hurtigere. Til dette kan du bruge @njit- dekoratøren.
Test af Numba-ydeevneforbedring i Python
Tid til at se på en simpel runtime-forbedringstest i Python. Nedenstående kode implementerer Numba for at have et hurtigere Python-program.
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))
I ovenstående kode kalder jit(nopython=True) brugen af @njit -deklaratoren. Når du kører ovenstående kode, vil output i terminalen være noget, der ligner det følgende (afhænger af maskin- og tilfældigt talgenereringsresultat)
9,1829195022583 1,2913379669189453 0,8751001358032227
Det betyder, at det tog 9,18 sek. at kalde funktionen rand_events() med n = 10.000.000. Efter at have anvendt @njit -deklaratoren og kørt funktionen igen, tager det kun 1,29 sek (inklusive at “jitte” funktionen). Uden opkaldet fra @njit -deklaratoren ville det tage 0,87 sek at kalde den “jittede” version af rand_events(). Det er en væsentlig forbedring af køretiden.
Anvender Numba til hurtigere Python-simuleringer
Numba kan gøre simuleringsrammer hurtigere. Men kun hvis store dele af rammen er numerisk orienteret. Derudover bør rammen integrere numpy , da numba forstår numpy udmærket. I en stærkt objektorienteret ramme kan dette være en udfordring. Men hvis du kan formå at omdanne beregningsintensive dele af koden til numerisk kode, kan numba resultere i betydelige runtime-forbedringer af Python-koden.
Industriingeniør som gerne beskæftiger sig med optimering, simulation og matematisk modellering i R, SQL, VBA og Python
Leave a Reply