Hurtigere Python-simulering med Numba

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.

You May Also Like

Leave a Reply

Leave a Reply

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *

This site uses Akismet to reduce spam. Learn how your comment data is processed.