Accelerating Python code with Numba¶
In [1]:
import math
import random
import numpy as np
from numba import jit, vectorize, float64
import matplotlib.pyplot as plt
import seaborn
%matplotlib inline
Random walk¶
In [2]:
def step():
return 1. if random.random() > .5 else -1.
In [3]:
def walk(n):
x = np.zeros(n)
dx = 1. / n
for i in range(n - 1):
x_new = x[i] + dx * step()
if x_new > 5e-3:
x[i + 1] = 0.
else:
x[i + 1] = x_new
return x
In [4]:
n = 100000
x = walk(n)
In [5]:
plt.plot(x)
In [6]:
%%timeit
walk(n)
Out[6]:
10 loops, best of 3: 57.6 ms per loop
In [7]:
@jit(nopython=True)
def step_numba():
return 1. if random.random() > .5 else -1.
In [8]:
@jit(nopython=True)
def walk_numba(n):
x = np.zeros(n)
dx = 1. / n
for i in range(n - 1):
x_new = x[i] + dx * step_numba()
if x_new > 5e-3:
x[i + 1] = 0.
else:
x[i + 1] = x_new
return x
In [9]:
%%timeit
walk_numba(n)
Out[9]:
The slowest run took 81.94 times longer than the fastest. This could mean that an intermediate result is being cached 1000 loops, best of 3: 1.89 ms per loop
Universal functions¶
In [10]:
x = np.random.rand(10000000)
%timeit np.cos(2*x**2 + 3*x + 4*np.exp(x**3))
Out[10]:
1 loops, best of 3: 689 ms per loop
In [11]:
@vectorize
def kernel(x):
return np.cos(2*x**2 + 3*x + 4*np.exp(x**3))
In [12]:
kernel(1.)
Out[12]:
-0.98639139715432589
In [13]:
%timeit kernel(x)
Out[13]:
1 loops, best of 3: 324 ms per loop
In [14]:
import numexpr
%timeit numexpr.evaluate('cos(2*x**2 + 3*x + 4*exp(x**3))')
Out[14]:
10 loops, best of 3: 122 ms per loop
In [15]:
numexpr.detect_number_of_cores()
Out[15]:
4