# Numba speeds up monte-carlo simulation In today’s post I will provide another example that shows how numba can speed up a numerical simulation. I apply the module to a monte-carlo simulation of stock price random walks. This is a popular monte-carlo simulation example and I also provided and example of this in a blog post several years ago.

## Monte-carlo simulation with numba in Python

In below code segment I import relevant modules and parts of modules. As I pointed out in an earlier post numba works very well with numpy, for example, but not that well with pandas. I implement two versions of a price random walk monte-carlo simulation. Both simulations repeat n random walks that have a duration of 365 days. Each day the price movement is randomly distributed in accordance with a random normal distribution with specified mean daily return and specified standard deviation of daily returns.

``````import numpy as np
from matplotlib import pyplot as plt
import random
import time
from numba import njit

def random_walker(n: int, length: int) -> np.ndarray:

arr = np.zeros((n, length), dtype = float)

for i in range(n):

idx = 100

for j in range(length):

idx += idx*random.gauss(0.00015, 0.02)

arr[i, j] = idx

return arr

@njit
def nb_random_walker(n: int, length: int) -> np.ndarray:

arr = np.zeros((n, length), dtype = float)

for i in range(n):

idx = 100

for j in range(length):

idx += idx*random.gauss(0.00015, 0.02)

arr[i, j] = idx

return arr``````

I now execute the random simulation runs. First, I run the simulation without numba. I do so two times. For each run I register the duration of simulation execution and print it into the terminal. After that I execute the numba-optimized simulation for a total of three times. For each time I print simulation runtime into the terminal for the purpose of being able to compare simulation runtimes.

You can see the code below:

``````# --- monte carlo run without numba ------------------
starttime = time.time()
arr = random_walker(10000, 365)
endtime = time.time()

print("monte carlo random walk without NUMBA; 1st time: ")
print(endtime-starttime)

starttime = time.time()
arr = random_walker(10000, 365)
endtime = time.time()

print("monte carlo random walk without NUMBA; 2nd time: ")
print(endtime-starttime)

# --- monte carlo run with numba --------------------
starttime = time.time()
arr = nb_random_walker(10000, 365)
endtime = time.time()

print("monte carlo random walk with NUMBA; 1st time: ")
print(endtime-starttime)

starttime = time.time()
arr = nb_random_walker(10000, 365)
endtime = time.time()

print("monte carlo random walk with NUMBA; 2nd time: ")
print(endtime-starttime)

starttime = time.time()
arr = nb_random_walker(10000, 365)
endtime = time.time()

print("monte carlo random walk with NUMBA; 3rd time: ")
print(endtime-starttime)``````

The output is as follows:

``````monte carlo random walk without NUMBA; 1st time:
1.9413235187530518
monte carlo random walk without NUMBA; 2nd time:
1.8833050727844238
monte carlo random walk with NUMBA; 1st time:
0.6361069679260254
monte carlo random walk with NUMBA; 2nd time:
0.07375526428222656
monte carlo random walk with NUMBA; 3nd time:
0.07474732398986816``````

In this case numba improved monte-carlo simulation runtime by almost factor 3 in the first run. For the second run and for every run after that the optimized monte-carlo simulation is more than 25 times faster! The first time the numba-optimized function is called it has to be “compiled”. For every call after that the function executes even faster – as you can see from above test results!

And by the way, this is what the random walks look like:

## Final remarks and related content

In this article I demonstrated how numba, a module in Python, makes monte-carlo simulations significantly faster. However, you must be aware of the constraints that come along with this module. As I pointed out you will be able to get the most out of numba if you have a numerical framework. Furthermore, be aware of the modules and packages that work well with numba – and the ones that don’t. For example, numpy works well with numba while pandas does not.