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