English | 中文 | 日本語 | Français | Deutsch
Dieses Projekt zeigt, wie Fibonacci in C++ implementiert und als natives Python-Erweiterungsmodul aus Python aufgerufen werden kann.
Nach dem Build kann Python das Modul so verwenden:
import fibonacci_cpp
print(fibonacci_cpp.fibonacci(10)) # 55- Python 3.x
- CMake 3.18 oder neuer
- Ein C++17-Compiler, zum Beispiel MinGW, MSVC oder Clang
Prüfen Sie, ob die benötigten Befehle verfügbar sind:
python --version
cmake --version
g++ --versionDas Python-Erweiterungsmodul muss mit derselben Python-Version gebaut und ausgeführt werden. Die CMake-Konfiguration dieses Projekts bevorzugt das python-Programm aus dem aktuellen Kommandozeilen-PATH, sodass das mit cmake --build build erzeugte Modul direkt über python main.py importiert werden kann.
Um einen bestimmten Python-Interpreter auszuwählen, konfigurieren Sie CMake so:
cmake -S . -B build -DPython_EXECUTABLE="C:\Users\YourName\miniconda3\python.exe"Führen Sie diese Befehle im Projektstamm aus:
cmake -S . -B build
cmake --build buildNach einem erfolgreichen Build enthält der Ordner build eine Datei ähnlich wie:
fibonacci_cpp.cp313-win_amd64.pyd
Das Python-Versionskennzeichen im Dateinamen kann abweichen. cp313 steht zum Beispiel für CPython 3.13.
Die zentrale CMake-Konfiguration lautet:
find_package(Python REQUIRED COMPONENTS Interpreter Development.Module)
add_library(fibonacci_cpp MODULE
src/fibonacci.cpp
)
target_link_libraries(fibonacci_cpp PRIVATE Python::Module)Das erzeugte Modul heißt fibonacci_cpp und wird in Python mit import fibonacci_cpp importiert.
src/fibonacci.cpp stellt über die Python C API eine Funktion bereit:
fibonacci_cpp.fibonacci(n)Hinweise:
nmuss eine nicht negative Ganzzahl sein.- Der Rückgabewert ist ein Python-
int, daher werden große Ergebnisse unterstützt. - Auf der C++-Seite wird
nderzeit alsunsigned long longeingelesen. Der größte akzeptierte Index ist also18446744073709551615. Die praktischen Grenzen hängen weiterhin von Speicher und Laufzeit ab.
Demo ausführen:
python main.pyGrößeren Benchmark ausführen:
python main.py 1000000main.py macht zwei Dinge:
- Es gibt kleine Beispiele von
fibonacci_cpp.fibonacci(0)bisfibonacci_cpp.fibonacci(10)aus. - Es vergleicht die Wall Time einer reinen Python-Implementierung mit der C++-Erweiterung für dasselbe große
n.
Standard-Benchmark:
python main.pyBeispielergebnis:
Benchmark n = 100,000
Result decimal digits : 20,899
Python Wall Time : 0.052376 s
C++ Wall Time : 0.000816 s
Speedup : 64.18x
Benchmark mit n = 1000000:
python main.py 1000000Beispielergebnis:
Benchmark n = 1,000,000
Result decimal digits : 208,988
Python Wall Time : 4.540529 s
C++ Wall Time : 0.033997 s
Speedup : 133.56x
Die Wall Time hängt von Maschine, Python-Version, Compiler und Hintergrundlast ab. Diese Zahlen sind daher nur Referenzwerte. Für genauere Messungen sollten mehrere Durchläufe gemittelt oder ein Werkzeug wie pyperf verwendet werden.
C++-Erweiterungen eignen sich gut für rechenintensive Hot Paths. In diesem Projekt:
- Die Python-Version nutzt eine einfache Schleife, sodass jeder Schritt über Python-Bytecode-Ausführung und Variablenbindung läuft.
- Die C++-Erweiterung verlagert die rechenintensive Logik in ein kompiliertes Modul und reduziert damit den Schleifen-Overhead auf Python-Ebene.
- Die C++-Implementierung verwendet schnelles Verdoppeln und berechnet Fibonacci mit ungefähr
O(log n)Großzahloperationen statt mitO(n)Schleifeniterationen. - Python übernimmt weiterhin Einstiegspunkt und Ausgabe, während C++ die schwere Berechnung erledigt.
Nicht jedes Python-Programm wird schneller, wenn Code nach C++ verschoben wird. Sprachübergreifende Aufrufe haben ebenfalls Kosten. Dieser Ansatz passt besonders gut zu stabiler, rechenintensiver Logik mit kontrollierter Aufruffrequenz.
-
Offizielles Python-Tutorial: Extending and Embedding the Python Interpreter
https://docs.python.org/3/extending/ -
Offizielle Python-Referenz: Python/C API Reference Manual
https://docs.python.org/3/c-api/index.html -
Real-Python-Tutorial: Building a Python C Extension Module
https://realpython.com/build-python-c-extension-module/ -
Für eine modernere C++-Abstraktion siehe pybind11
https://pybind11.readthedocs.io/
