Mixed programming with Python#
Is Python slow for numerical computing?#
Task: Fill a NumPy array with function values.
Python implementation#
from math import sin
import numpy as np
n = 2000
a = np.zeros((n, n))
xcoor = np.arange(0, 1, 1 / float(n))
ycoor = np.arange(0, 1, 1 / float(n))
def f(x, y):
return sin(x**2 + y)
%%time
for i in range(n):
for j in range(n):
a[i, j] = f(xcoor[i], ycoor[j])
CPU times: user 1.23 s, sys: 9.73 ms, total: 1.24 s
Wall time: 1.25 s
Timings#
Version |
Time (normalised) |
---|---|
Fortran/C/C++ version |
1.0 |
NumPy vectorized evaluation of |
3.0 |
Python loop version ( |
140 |
Python loop version ( |
350 |
Conclusions#
Python loops over arrays are extremely slow
NumPy vectorization may be sufficient
However, sometimes plain loops in Fortran/C/C++ are easier
Why are version in the compiled languages faster?#
Optimizations of C, C++, and Fortran:
Compilers do a good job for C, C++, and Fortran.
The type system makes agressive optimization possible.
Examples: code inlining, loop unrolling, and memory prefetching.
In contrast, in Python we have:
No compiler.
No type declaration of variables.
No inlining and no loop unrolling.
Probably inefficient in Python:
def f(a, b): return a + b
Overview of mixed programming tools#
Extending vs embedding Python#
Python can be mixed with other languages in two ways:
By extending Python with libraries and functions written in other languages
By embedding, i.e. calling Python from inside a program written in another language
We only consider extending Python. This has two main use cases:
Accessing functions in existing libraries written in C or C++, to avoid re-inventing existing tools
Speeding up a Python program by migrating slow code (e.g. loops) to C or C++
Summary of mixed-programming tools#
Hand written wrapper code using the Python-C-API;
[+] General, low level control, no need for additional libraries and tools
[-] Time consuming, significant overhead
ctypes
Provides C compatible data types, and allows calling functions in shared libraries.
[+] Part of the standard Python library, no need for compiling, all wrapper code is written in Python
[-] Low support for C++, Python wrapper code introduces overhead
Cython
Extends the Python language with elements from C
can write pure Python
Python/Cython code is compiled and available as a Python module
Lots of advanced tools and possibilities
Numba
Uses Just in Time compilation (JIT) to speed up Python code
[+] (Almost) fully automatic
[o] Seems magical, which can make debugging more tricky
[-] Needs to be installed as runtime dependency
pybind11
[+] powerful for complex bindings to C++
Good for C++ experts who need Python bindings