# Numba: Python’s lord and savior

--

When it comes to high performance computing (HPC), people often think of programming languages like C/C++ or Fortran, especially in the scientific community. Some more adventurous people may even try Julia. However, almost no one ever thinks “let me write a HPC application in Python” unless they really know what they are doing and know how to test it thoroughly under different conditions. This is simply because Python is an interpreted language at its very core and does not care much for performance unless you use very specialized libraries like NumPy, Pandas or SciPy which are written in a way that emulates the performance of C or Fortran. And for the most part, these are very good libraries and can do quite a lot of stuff, almost as fast as C of Fortran can, especially with numerical computing things like linear algebra, statistics, or solving differential equations numerically.

There is however the issue of “this doesn’t actually always work” which makes Python developers like myself rather frustrated when faced with a problem that *feels* like it should be straight-forward to solve, in a reasonable amount of time, but actually isn’t in Python. To give you an example of this, something I worked on for quite some time involved performing some calculations inside a double-for loop.

The details of this are not important, but just so you get a gist of the problem, it all comes down to performing a calculation using a very lengthy formula. Each of these calculations requires performing 64 calls to that formula with different input parameters in sequence (which must in fact be done using a triple-nested loop), and this must be repeated hundreds of thousands of times sequentially using a double-loop.

So as you may imagine, this is a very lengthy computation which might be fine in a low-level language, but in Python: oh boy, be ready for blood, sweat and tears. Doing a triple for-loop inside a double-for loop? Sounds like a recipe for disaster. Here is what the main code would look like:

`def calculatedMatrix(x_vec, y_vec, ...):`

Matrix = []

for ii in range(x_vec):

for jj in range(y_vec):

# ... load up relevant values from x_vec and y_vec

value = # --> call formula(x,y,z)

Matrix.append(value)

return Matrix

def formula(x,y,z):

return # some…