16 Leistungsoptimierung

Python ist zwar sehr flexibel und einfach zu schreiben, jedoch nicht immer die schnellste Sprache. Für leistungskritische Anwendungen gibt es mehrere Möglichkeiten, Python-Code zu beschleunigen, oft durch die Integration von C/C++ oder durch JIT-Compiler.

1 Cython

Cython ist eine Erweiterung von Python, mit der man C-ähnlichen Code schreiben kann, der zu sehr schnellem C-Code kompiliert wird. Es erlaubt auch das Einbinden von C-Bibliotheken.

Die Verwendung lohnt sich nur, wenn man sehr viele mathematische Operationen durchführt.

1.1 Beispiel

# example.pyx

def compute_sum(int n):
    cdef int i
    cdef int total = 0
    for i in range(n):
        total += i
    return total

Um diesen Code zu verwenden, muss er mit Cython kompiliert werden, z. B. über setup.py oder Jupyter mit %%cython.

2 CPython

CPython ist die Standard-Implementierung von Python, geschrieben in C. Bei der Optimierung auf CPython-Ebene kann man z. B. direkt in C Erweiterungsmodule schreiben.

2.1 Vorteile

  • Maximale Performance durch nativen C-Code
  • Direkter Zugriff auf Python-Interna
  • Verwendung für systemnahe Programmierung

2.2 Nachteile

  • Komplexität des C-Codes
  • Manuelle Speicherverwaltung

3 Pybind11 (C++)

Pybind11 ist eine moderne Header-only-C++-Bibliothek zur Anbindung von C++-Code an Python. Sie erlaubt es, bestehende C++-Bibliotheken einfach in Python zu verwenden.

3.1 Beispiel

#include <pybind11/pybind11.h>
int add(int a, int b) {
    return a + b;
}

PYBIND11_MODULE(my_module, m) {
    m.def("add", &add);
}

Kompiliert wird dies zu einer .so-Datei, die in Python importiert werden kann:

import my_module
print(my_module.add(3, 4))  # Ausgabe: 7
Was ist eine Header-only-C++-Bibliothek?

In C++ bestehen Bibliotheken typischerweise aus:

  • Header-Dateien (.h oder .hpp) – enthalten Deklarationen (z. B. Funktionen, Klassen).
  • Implementierungsdateien (.cpp) – enthalten die eigentliche Logik.

Eine Header-only-Bibliothek verzichtet auf .cpp-Dateien.
Stattdessen ist die gesamte Implementierung direkt in den Header-Dateien enthalten. Das bedeutet:

  • Man muss die Bibliothek nicht kompilieren – man bindet einfach nur die Header-Datei ein.
  • Sie kann per #include benutzt werden.
  • Beispiel: #include <pybind11/pybind11.h>

Vorteile:

  • Einfacher zu integrieren, kein separater Build-Schritt nötig.
  • Portabler, da es keine Abhängigkeit zu vorcompilierten Binaries gibt.
  • Gut geeignet für Templates und generischen Code.

Nachteil:

  • Der Compiler sieht bei jedem #include die komplette Implementierung → längere Compile-Zeiten.

4 Numba

Numba ist ein JIT-Compiler (Just-In-Time), der Funktionen zur Laufzeit in optimierten Maschinen-Code übersetzt, basierend auf LLVM.

4.1 Beispiel

from numba import jit

@jit(nopython=True)
def fast_sum(n):
    total = 0
    for i in range(n):
        total += i
    return total

print(fast_sum(1000000))

Numba funktioniert besonders gut bei numerischen Berechnungen und Schleifen.

Was ist LLVM?

LLVM steht für "Low-Level Virtual Machine", ist aber heute viel mehr als das: LLVM ist eine moderne Compiler-Infrastruktur, die aus mehreren modularen Tools besteht. Viele moderne Programmiersprachen verwenden LLVM, um ihren Code in Maschinencode zu übersetzen.

Wichtigste Eigenschaften:

  • Zwischensprache (IR): LLVM übersetzt Code zuerst in eine eigene "Intermediate Representation" (IR), die dann weiter optimiert wird.
  • Optimierungen: Bietet sehr fortschrittliche Optimierungen auf niedriger Ebene.
  • Backend: Erzeugt optimierten Maschinencode für viele Plattformen.

Beispiele für Tools/Projekte, die LLVM nutzen:

  • Clang (C/C++-Compiler)
  • Rust
  • Swift
  • Numba (s. o.)
  • Julia

Warum wichtig für Python-Optimierung?
Numba nutzt LLVM, um Python-Funktionen zur Laufzeit (JIT) in schnellen Maschinen-Code umzuwandeln.

5 Mypyc

Mypyc kompiliert typannotierten Python-Code zu C-Extensions und kann so erhebliche Geschwindigkeitsvorteile bringen. Es arbeitet zusammen mit mypi, dem statischen Typprüfer.

5.1 Beispiel

# example.py

def double(x: int) -> int:
    return x * 2

Kompilieren mit mypyc:

mypyc example.py

Die resultierende .so-Datei kann dann wie ein normales Python-Modul importiert werden.

5.2 Vorteile

  • Nahtlose Integration mit typisiertem Python-Code
  • Einfache Anwendung über bestehende Typannotationen