Everyone wishes their code was more efficient — here’s the implementation and why of a simple trick that requires minimal effort but drastically improves performance.
Consider the Mandelbrot Set, a fascinating mathematical phenomena involving bit operations, recursion, and imaginary numbers. Because it’s such a complicated and computationally diverse function, it is a great case study on how to improve efficiency. An in-depth code explanation and beautiful images of the produced result can be found here.
import numpy as np
def mandelbrot_set(width, height, zoom=1, x_off=0, y_off=0, niter=256):
w,h = width, height
pixels = np.arange(w*h, dtype=np.uint16).reshape(h, w)
for x in range(w):
for y in range(h):
zx = 1.5*(x + x_off - 3*w/4)/(0.5*zoom*w)
zy = 1.0*(y + y_off - h/2)/(0.5*zoom*h)
z = complex(zx, zy)
c = complex(0, 0)
for i in range(niter):
if abs(c) > 4: break
c = c**2 + z
color = (i << 21) + (i << 10) + i * 8
pixels[y,x] = color
Timing our function mandelbrot_set
, we find that this expensive function takes, on average, about 8 seconds to run.
%timeit mandelbrot_set(800,300)
[OUTPUT]: 7.96 s ± 160 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Let’s make one simple change: in a separate cell, we will load Cython, a module dedicated to bridging the gap between C and Python (more on this later). Then, at the top of the cell, we will type %%cython -a
, triggering Jupyter Notebook’s line magics to run the code through Cython, which automatically converts Python code into C behind the scenes. Our function, mandelbrot_set
, can be called in Python but will be run with C structures.
#programming #data-science #computer-science #python #ai