Wie machbar wäre es, Python (möglicherweise über eine C-Zwischendarstellung) in Maschinencode zu kompilieren?
Vermutlich müsste eine Verknüpfung zu einer Python-Laufzeitbibliothek hergestellt werden, und alle Teile der Python-Standardbibliothek, die selbst Python waren, müssten ebenfalls kompiliert (und eingebunden) werden.
Außerdem müssten Sie den Python-Interpreter bündeln, wenn Sie Ausdrücke dynamisch auswerten möchten, aber möglicherweise wäre eine Teilmenge von Python, die dies nicht zulässt, dennoch nützlich.
Würde es Vorteile hinsichtlich Geschwindigkeit und / oder Speichernutzung bieten? Vermutlich würde die Startzeit des Python-Interpreters entfallen (obwohl gemeinsam genutzte Bibliotheken beim Start noch geladen werden müssten).
python
c
linker
compilation
Andy Bileam
quelle
quelle
Antworten:
Probieren Sie den ShedSkin Python-to-C ++ - Compiler aus, aber er ist alles andere als perfekt. Es gibt auch Psyco - Python JIT, wenn nur eine Beschleunigung erforderlich ist. Aber meiner Meinung nach ist das die Mühe nicht wert. Für geschwindigkeitskritische Teile des Codes besteht die beste Lösung darin, sie als C / C ++ - Erweiterungen zu schreiben.
quelle
Wie @ Greg Hewgill sagt, gibt es gute Gründe, warum dies nicht immer möglich ist. Bestimmte Arten von Code (wie sehr algorithmischer Code) können jedoch in "echten" Maschinencode umgewandelt werden.
Es gibt mehrere Möglichkeiten:
Danach können Sie eines der vorhandenen Pakete (Freeze, Py2exe, PyInstaller) verwenden, um alles in eine Binärdatei zu packen.
Alles in allem gibt es keine allgemeine Antwort auf Ihre Frage. Wenn Sie leistungskritischen Python-Code haben, versuchen Sie, so viele integrierte Funktionen wie möglich zu verwenden (oder stellen Sie die Frage "Wie mache ich meinen Python-Code schneller?"). Wenn dies nicht hilft, versuchen Sie, den Code zu identifizieren und nach C (oder Cython) zu portieren, und verwenden Sie die Erweiterung.
quelle
py2c ( https://github.com/pradyun/Py2C ) kann Python-Code in c / c ++ konvertieren. Ich bin der Solo-Entwickler von py2c.
quelle
PyPy ist ein Projekt zur Neuimplementierung von Python in Python, bei dem die Kompilierung zu nativem Code als eine der Implementierungsstrategien verwendet wird (andere sind VMs mit JIT, JVM usw.). Ihre kompilierten C-Versionen laufen im Durchschnitt langsamer als CPython, bei einigen Programmen jedoch viel schneller.
Shedskin ist ein experimenteller Python-zu-C ++ - Compiler.
Pyrex ist eine Sprache, die speziell zum Schreiben von Python-Erweiterungsmodulen entwickelt wurde. Es wurde entwickelt, um die Lücke zwischen der schönen, benutzerfreundlichen Welt von Python auf hoher Ebene und der chaotischen Welt von C auf niedriger Ebene zu schließen.
quelle
Nuitka ist ein Python-zu-C ++ - Compiler, der mit libpython verknüpft ist. Es scheint ein relativ neues Projekt zu sein. Der Autor behauptet eine Geschwindigkeitsverbesserung gegenüber CPython im Pystone-Benchmark.
quelle
Dies mag auf den ersten Blick vernünftig erscheinen, es gibt jedoch viele gewöhnliche Dinge in Python, die nicht direkt auf eine C-Darstellung abgebildet werden können, ohne einen Großteil der Python-Laufzeitunterstützung zu übernehmen. Zum Beispiel fällt mir das Tippen von Enten ein. Viele Funktionen in Python, die Eingaben lesen, können eine Datei oder eine Datei enthalten Objekt , sofern sie bestimmte Operationen unterstützen, z. read () oder readline (). Wenn Sie darüber nachdenken, was erforderlich ist, um diese Art der Unterstützung C zuzuordnen, stellen Sie sich genau vor, was das Python-Laufzeitsystem bereits tut.
Es gibt Dienstprogramme wie py2exe , die ein Python-Programm und die Laufzeit in einer einzigen ausführbaren Datei bündeln (soweit möglich).
quelle
foo.x
Ausdruck wird nicht funktionieren , weilfoo
nicht habenx
zu der Zeit sie aufgerufen wird. Gibt es statische Codeprüfer für Python? Python kann zu einer .Net-Assembly kompiliert werden ...Pyrex ist eine Teilmenge der Python-Sprache, die zu C kompiliert wird und von dem Typ erstellt wurde, der zuerst Listenverständnisse für Python erstellt hat. Es wurde hauptsächlich für das Erstellen von Wrappern entwickelt, kann jedoch in einem allgemeineren Kontext verwendet werden. Cython ist eine aktivere Pyrexgabel.
quelle
Einige zusätzliche Referenzen:
https://github.com/dropbox/pyston ist ein JIT-Compiler für Python, der von Dropbox entwickelt wurde
http://pythran.readthedocs.io/ ist ein Python-zu-C ++ - Übersetzer zur Kompilierungszeit für wissenschaftliches Rechnen
https://github.com/cosmo-ethz/hope ist ein JIT-Python-zu-C ++ - Übersetzer für wissenschaftliches Rechnen
quelle
Jython verfügt über einen Compiler, der auf JVM-Bytecode abzielt. Der Bytecode ist voll dynamisch, genau wie die Python-Sprache selbst! Sehr cool. (Ja, wie Greg Hewgills Antwort anspielt, verwendet der Bytecode die Jython-Laufzeit, und daher muss die Jython-JAR-Datei mit Ihrer App verteilt werden.)
quelle
Psyco ist eine Art Just-in-Time-Compiler (JIT): Dynamischer Compiler für Python, der Code 2-100-mal schneller ausführt, aber viel Speicher benötigt.
Kurz gesagt: Es führt Ihre vorhandene Python-Software viel schneller aus, ohne dass sich Ihre Quelle ändert, aber es wird nicht wie ein C-Compiler zu Objektcode kompiliert.
quelle
Die Antwort lautet "Ja, das ist möglich". Sie können Python-Code verwenden und versuchen, ihn mithilfe der CPython-API in den entsprechenden C-Code zu kompilieren. Tatsächlich gab es früher ein Python2C-Projekt, das genau das tat, aber ich habe seit vielen Jahren nichts mehr davon gehört (in den 1,5 Tagen von Python habe ich es das letzte Mal gesehen).
Sie können versuchen, den Python-Code so weit wie möglich in natives C zu übersetzen und auf die CPython-API zurückzugreifen, wenn Sie tatsächliche Python-Funktionen benötigen. Ich habe in den letzten ein oder zwei Monaten selbst mit dieser Idee gespielt. Es ist jedoch eine Menge Arbeit, und eine enorme Menge von Python-Funktionen ist sehr schwer in C zu übersetzen: verschachtelte Funktionen, Generatoren, alles andere als einfache Klassen mit einfachen Methoden, alles, was das Ändern von Modulglobalen von außerhalb des Moduls usw. , etc.
quelle
Dadurch wird Python nicht zu Maschinencode kompiliert. Ermöglicht jedoch das Erstellen einer gemeinsam genutzten Bibliothek zum Aufrufen von Python-Code.
Wenn Sie nach einer einfachen Möglichkeit suchen, Python-Code von C aus auszuführen, ohne sich auf Execp-Inhalte verlassen zu müssen. Sie können eine gemeinsam genutzte Bibliothek aus Python-Code generieren, der mit einigen Aufrufen der Python-Einbettungs-API umschlossen ist . Nun, die Anwendung ist eine gemeinsam genutzte Bibliothek, eine .so, die Sie in vielen anderen Bibliotheken / Anwendungen verwenden können.
Hier ist ein einfaches Beispiel, das eine gemeinsam genutzte Bibliothek erstellt, die Sie mit einem C-Programm verknüpfen können. Die gemeinsam genutzte Bibliothek führt Python-Code aus.
Die Python-Datei, die ausgeführt wird, lautet
pythoncalledfromc.py
:Sie können es mit versuchen
python2 -c "import pythoncalledfromc; pythoncalledfromc.main('HELLO')
. Es wird ausgegeben:Die gemeinsam genutzte Bibliothek wird wie folgt definiert
callpython.h
:Das zugehörige
callpython.c
ist:Sie können es mit dem folgenden Befehl kompilieren:
Erstellen Sie eine Datei mit dem Namen
callpythonfromc.c
, die Folgendes enthält:Kompilieren Sie es und führen Sie Folgendes aus:
Dies ist ein sehr einfaches Beispiel. Es kann funktionieren, aber je nach Bibliothek kann es immer noch schwierig sein, C-Datenstrukturen nach Python und von Python nach C zu serialisieren. Die Dinge können etwas automatisiert werden ...
Nuitka könnte hilfreich sein.
Es gibt auch Numba, aber beide wollen nicht genau das tun, was Sie wollen. Das Generieren eines C-Headers aus Python-Code ist möglich, jedoch nur, wenn Sie angeben, wie die Python-Typen in C-Typen konvertiert werden sollen, oder auf diese Informationen schließen können. Siehe Python Astroid für einen Python Ast Analyzer.
quelle