Ich habe Python nur als Erweiterung von Shell-Skripten verwendet, aber kürzlich habe ich es für eine etwas anständigere Verwendung verwendet. Dann fragte ich mich als Low-Layer-Enthusiast, wie Python ausgeführt wurde. Also nahm ich es auf und aß es.
Die Geschichte, dass die Sprachspezifikation und Implementierung verschiedene Dinge sind.
Es gibt nur eine Sprache, Python, aber es gibt mehr als einen Weg, um die Funktionalität dieser Sprache zu erreichen. CPython und PyPy sind die Namen für die Implementierung der Sprache Python. Apropos C-Sprache: GCC oder Clang können als Compiler ausgewählt werden. Informationen zu den Arten von Python-Implementierungen finden Sie unter Python Wikipedia. Es gibt ziemlich viele.
Unter verschiedenen Implementierungen ist CPython die sogenannte Referenzimplementierung, die vom ursprünglichen Autor von Python implementiert wird, und die Python-Ausführungsumgebung in der Welt ist ungefähr diese, was genau die ursprüngliche Position ist.
Wie Sie sich aus dem Namen vorstellen können, ist CPython in der Sprache C und PyPy in Python implementiert. Und PyPy ist schneller als CPython. Hmm? Was bedeutet es, dass PyPy schneller als CPython ist, wenn C schneller als Python ist? Ich möchte das etwas erklären.
Wenn Sie CPython Wikipedia lesen,
CPython ist ein Bytecode-Interpreter.
ein. Hmm, Bytecode-Interpreter. Was ist es?
Ein Bytecode ist ein Zwischenausdruck. Mit anderen Worten, in der CPython-Umgebung wird Python zuerst in Bytecode konvertiert und der Bytecode wird von der virtuellen Maschine (VM) ausgeführt. Es wird als Bytecode-Interpreter bezeichnet, da es Byte-Codes nacheinander interpretiert und ausführt.
Der Grund dafür scheint zu sein, dass es schneller ist, aber ich bin mir nicht sicher, warum die Gesamtausführungszeit mit dem Bytecode in der Sprache, die auf dem Interpreter ausgeführt wird, entscheidend schneller ist. Es gab keine. Zumindest die Implementierung des Interpreters wird jedoch aktualisiert, und wenn der Bytecode als Cache belassen wird, wird der größte Teil der Verarbeitung, wie z. B. die Syntaxanalyse, ab dem zweiten Mal nicht mehr ausgeführt, und dies scheint definitiv sinnvoll zu sein. Wenn Sie Python-Code ausführen, werden .pyc-Dateien und \ _ \ _ pycache \ _ \ _ -Verzeichnisse erstellt, aber es scheint, dass in diesen Bytecodes aufgezeichnet sind. Es scheint möglich zu sein, nur diese Bytecodes in eine andere Umgebung zu übertragen und auszuführen.
Das? Übrigens gibt es eine berühmte Sprache mit solchen Spezifikationen. Ja, Java. Am Anfang der Java-Beschreibung steht eine Beschreibung, dass Java-Code in Byte-Code konvertiert wird und von Jave VM ausgeführt wird. Sowohl in Python als auch in Java wird der Quellcode in Bytecode konvertiert (kompiliert) und dann von der VM (Interpreter) ausgeführt. Java wird als Kompilierungssprache und Python als Interpretersprache erkannt. In Wirklichkeit erfolgt die Kompilierung jedoch explizit oder implizit.
Warum ist PyPy in Python schneller als CPython geschrieben? Dies liegt daran, dass die JIT-Kompilierung (Just In Time) durchgeführt wird.
Was ist JIT-Kompilierung? Grob gesagt wird es beim Ausführen in eine Maschinensprache kompiliert und dann ausgeführt, sodass es schneller ist. Betrachten Sie beispielsweise die Schleifenverarbeitung und Funktionen, die häufig aufgerufen werden. Wenn es sich um einen einfachen Interpreter handelt, wird die Grammatik jedes Mal interpretiert, wenn diese Codes aufgerufen werden, und der Interpreter führt die Verarbeitung basierend auf dem Inhalt aus. Da der tatsächliche Status des Interpreters natürlich eine Sammlung von Maschinenwörtern ist, ist es schließlich so, als würde die Maschinensprache jedes Mal ausgeführt, nachdem der Code ⇒ Maschinensprachenkonvertierung durchgeführt wurde. Wenn dann der Code, der wiederholt aufgerufen wird, zusammen in eine Maschinensprache konvertiert wird und die Maschinensprache direkt ausgeführt wird, wenn derselbe Code aufgerufen wird, scheint es, dass die Konvertierungsverarbeitungszeit reduziert werden kann. Darüber hinaus kann ein Interpreter, der Code zeilenweise konvertiert, nicht basierend auf dem Verarbeitungsablauf optimiert werden. Wenn der Code jedoch bis zu einem gewissen Grad in einem Stapel gelesen und konvertiert wird, ist möglicherweise eine gewisse Optimierung möglich. ..
Es gibt jedoch verschiedene Methoden zur Beschleunigung durch JIT-Kompilierung, und ich verstehe ehrlich gesagt nicht, was der Schlüssel zur Beschleunigung ist. Darüber hinaus scheint PyPy eine spezielle Methode zum JIT-Kompilieren des Verarbeitungscodes anzuwenden, und es scheint schwierig zu sein, den Inhalt zu verstehen.
Wenn Sie sich die PyPy-Download-Seite ansehen, wird übrigens angegeben, dass der JIT-Compiler nur auf Intel-basierten CPUs funktioniert.
These binaries include a Just-in-Time compiler. They only work on x86 CPUs that have the SSE2 instruction set (most of them do, nowadays), or on x86-64 CPUs. They also contain stackless extensions, like greenlets.
Ich vermute, weil ich die Quelle nicht überprüft habe, aber die JIT-Kompilierung bedeutet, dass es im Sprachverarbeitungssystem einen Prozess gibt, der eine Assembly generiert, die von der CPU-Architektur abhängt. Die Implementierung einer Verarbeitung, die vielen CPU-Architekturen auf der Welt entspricht, ist eine schwierige Aufgabe. Es kann nur für Intel-CPUs mit einer großen Anzahl von Benutzern implementiert werden.
Wenn Sie PyPy verwenden und Python-Code ausführen, wird dieser von PyPy gelesen und ausgeführt. Wer führt PyPy aus, das in Python geschrieben ist? Anscheinend wurde PyPys Python-Code in C konvertiert und in Binär kompiliert.
Ich fand, dass PyPy einen eingebauten JIT-Compiler hat und schnell ist, aber Python hatte übrigens eine Bibliothek namens Numba, die JIT kompiliert. Wenn man sich den Numba Guide ansieht, scheint er eine angemessene Anzahl von CPU-Architekturen zu unterstützen.
Architecture: x86, x86_64, ppc64le. Experimental on armv7l, armv8l (aarch64).
Arbeitet Numba hart daran, die Unterstützung pro Architektur zu implementieren?
Nach ein wenig Recherche scheint Numba LLVM zu verwenden. Wenn Sie LLVM verwenden und den Python-Code in LLVM IR (einen Zwischenausdruck von LLVM) konvertieren, verarbeitet die LLVM jede CPU-Architektur, sodass sie auf der Numba-Seite nicht unterstützt werden muss.
Ich habe versucht herauszufinden, wie Python-Code nach Belieben ausgeführt wird. Ich hatte das Gefühl, dass es fast keine Grenze zwischen der Interpretersprache und der Compilersprache gibt. Es wird aus Gründen der Geschwindigkeit in der Interpretersprache kompiliert, und einige Kompilierungssprachen funktionieren der Einfachheit halber wie ein Interpreter. Ich dachte, ich wüsste etwas über die JIT-Kompilierung, aber ich kannte die Details überhaupt nicht.
Wie ist das Python-Verarbeitungssystem implementiert und wie funktioniert es? Wird Python einzeln interpretiert oder kompiliert?
Recommended Posts