2016-03-03 10 views
6

Von dem, was ich gelesen habe, kann Numba ein Python-Programm erheblich beschleunigen. Könnte die Zeiteffizienz meines Programms mit numba erhöht werden?Verwenden Sie Numba, um für die Schleife zu beschleunigen

import numpy as np 

def f_big(A, k, std_A, std_k, mean_A=10, mean_k=0.2, hh=100): 
    return (1/(std_A * std_k * 2 * np.pi)) * A * (hh/50) ** k * np.exp(-1*(k - mean_k)**2/(2 * std_k **2) - (A - mean_A)**2/(2 * std_A**2)) 

outer_sum = 0 
dk = 0.000001 
for k in np.arange(dk,0.4, dk): 
    inner_sum = 0 
    for A in np.arange(dk, 20, dk): 
     inner_sum += dk * f_big(A, k, 1e-5, 1e-5) 
    outer_sum += inner_sum * dk 

print outer_sum 

Antwort

5

Ja, das ist die Art von Problem, für das Numba wirklich funktioniert. Ich habe Ihren Wert von dk geändert, weil es für eine einfache Demonstration nicht sinnvoll war. Hier ist der Code:

import numpy as np 
import numba as nb 

def f_big(A, k, std_A, std_k, mean_A=10, mean_k=0.2, hh=100): 
    return (1/(std_A * std_k * 2 * np.pi)) * A * (hh/50) ** k * np.exp(-1*(k - mean_k)**2/(2 * std_k **2) - (A - mean_A)**2/(2 * std_A**2)) 

def func(): 
    outer_sum = 0 
    dk = 0.01 #0.000001 
    for k in np.arange(dk, 0.4, dk): 
     inner_sum = 0 
     for A in np.arange(dk, 20, dk): 
      inner_sum += dk * f_big(A, k, 1e-5, 1e-5) 
     outer_sum += inner_sum * dk 

    return outer_sum 

@nb.jit(nopython=True) 
def f_big_nb(A, k, std_A, std_k, mean_A=10, mean_k=0.2, hh=100): 
    return (1/(std_A * std_k * 2 * np.pi)) * A * (hh/50) ** k * np.exp(-1*(k - mean_k)**2/(2 * std_k **2) - (A - mean_A)**2/(2 * std_A**2)) 

@nb.jit(nopython=True) 
def func_nb(): 
    outer_sum = 0 
    dk = 0.01 #0.000001 
    X = np.arange(dk, 0.4, dk) 
    Y = np.arange(dk, 20, dk) 
    for i in xrange(X.shape[0]): 
     k = X[i] # faster to do lookup than iterate over an array directly 
     inner_sum = 0 
     for j in xrange(Y.shape[0]): 
      A = Y[j] 
      inner_sum += dk * f_big_nb(A, k, 1e-5, 1e-5) 
     outer_sum += inner_sum * dk 

    return outer_sum 

Und dann Timings:

In [7]: np.allclose(func(), func_nb()) 
Out[7]: True 

In [8]: %timeit func() 
1 loops, best of 3: 222 ms per loop 

In [9]: %timeit func_nb() 
The slowest run took 419.10 times longer than the fastest. This could mean that an intermediate result is being cached 
1000 loops, best of 3: 362 µs per loop 

So ist die numba Version ist ca. 600 mal schneller auf meinem Laptop.

+0

Vielleicht pingelig, aber anstatt "@ nb.jit (nopython = True)" '' zu verwenden, können Sie '' nb.njit'' verwenden, ohne '' nopython = True''. – MSeifert

+2

@MSeifert Ich neige dazu, diese Form von Gewohnheit zu verwenden, da ich es oft parametrisieren werde, so dass ich während des Testens leicht hin und her wechseln kann – JoshAdel

Verwandte Themen