Just-In-Time (JIT) Compiler: Was es ist und wie es in der Programmierung funktioniert

Programmieren ist nicht nur das Schreiben von Code in einem Editor. Es ist der gesamte Prozess von der Vorbereitung des Projekts über das Schreiben des Pseudocodes und die Umwandlung in Code bis hin zur Kompilierung und Fehlersuche und der Überprüfung, ob es tatsächlich richtig läuft. Alle diese Schritte sind innerhalb eines Projekts wichtig. Aber einer derjenigen, von denen wir am wenigsten wissen, wie sie funktionieren, und die verschiedenen Typen, die es gibt, ist der letzte, die Zusammenstellung. Und das werden wir heute lernen.

Was ist kompilieren?

Just-In-Time (JIT)-Compiler

Sofern wir nicht in Binärprogrammen oder in einer sehr, sehr niedrigen Sprache wie Assembler programmieren, verstehen Maschinen die Codezeilen, die wir schreiben, nicht. Und je höher die Sprache, die wir verwenden, desto natürlicher wird sie für uns, aber desto komplexer wird sie für die Maschine sein. Und deshalb müssen wir, um unsere Hochsprache in Maschinensprache umzuwandeln, kompiliere den Code .

Das Kompilieren des Codes ist der Prozess, mit dem wir unsere High-Level-Codezeilen in Maschinensprache konvertieren. Dazu benötigt man zum einen eine reine Textdatei mit dem gesamten Code und zum anderen ein Programm, das Compiler , die für die Konvertierung jeder der Codezeilen in binäre oder in die entsprechende Low-Level-Sprache verantwortlich ist.

Esquema kompilierte Programme

Dank der Verwendung dieser Compiler ist die Programmierung sehr einfach, und derselbe Code kann mit einigen Anpassungen auf verschiedenen Maschinentypen verwendet werden. Da diese Programme für die Arbeit mit bestimmten Architekturen optimiert sind, bieten sie außerdem in der Regel eine gute Gesamtleistung. Allerdings nicht alle Vorteile. Ein kompiliertes Programm funktioniert nur auf dem Computer, für den der Compiler entwickelt wurde, zum Beispiel ein x64 CPU or ARM Prozessor. Je nach Betriebssystem ist es auch notwendig, das gleiche Programm mehrmals zu kompilieren (WindowsmacOS Linux, Android, iOS, etc.), wo wir es ausführen werden.

Differenzen mit dem Dolmetscher

Dolmetscher werden genau erstellt, um die beiden Probleme zu lösen, die wir gerade bei Compilern gesehen haben. Dies sind Programme, die zwischen unserem Originalcode und unserer Maschine laufen und für die Interpretation jeder der Anweisungen abhängig von der Maschine oder dem Betriebssystem verantwortlich sind, auf der wir sie ausführen.

Diese Interpreter werden an derselben Stelle platziert, an der die Compiler mit der Übersetzung des Codes beginnen würden. Somit beseitigen sie alle Betriebssystem- oder Plattformbeschränkungen und können für alles denselben Code verwenden.

Natürlich können wir nicht glauben, dass ein Dolmetscher perfekt ist. Das erste, was Sie beachten sollten, ist, dass diese nicht für alle Arten von Programmiersprachen gültig sind. Die Interpreter können beispielsweise mit Python oder JavaScript arbeiten, wären aber in anderen Sprachen wie C++ nicht lauffähig. Außerdem bedeutet die Notwendigkeit, den Code gleichzeitig mit seiner Ausführung interpretieren zu müssen, einen erheblichen Leistungsverlust, da jeder Befehl übersetzt und behandelt werden muss, als ob er ein separater Compiler wäre.

Und hier kommen die JIT-Compiler ins Spiel.

Was ist ein Just-In-Time-Compiler?

Während ein normaler Compiler dafür verantwortlich ist, den gesamten Code zu kompilieren, wenn wir das Programm ausführen, den Code in Binär umwandeln und die ausführbare Datei generieren, optimiert der JIT-Compiler diese Arbeit, indem er Kompilieren Sie nur den Code jeder Funktion, wenn dies erforderlich ist. .

Auf diese Weise kompiliert der Just-In-Time- oder JIT-Compiler beim Ausführen eines Programms nur die Funktionen, die in diesem Moment verwendet werden, und speichert das Ergebnis in einem Cache. Wenn wir das Programm verwenden, wird eine neue Funktion, die noch nicht kompiliert wurde, erneut kompiliert. Wenn wir jedoch eine bereits verwendete Funktion finden, wird sie, anstatt sie erneut zu kompilieren, im Cache durchsucht, was viel Zeit spart.

Einige Anwendungsbeispiele JIT-Compiler sind wie folgt:

  • Java: Die virtuelle Java-Maschine JVM verwendet Just-In-Time.
  • .NET Framework – Microsofts Programmierumgebung.
  • C#: CLR (Common Language Runtime).
  • Android: bei Verwendung mit DVM (Dalvik Virtual Machine) oder ART (Android RunTime).
  • Emulatoren: Diese Compiler werden auch in Emulatoren für Konsolen und andere PCs verwendet. Auf diese Weise wird Maschinencode von einer CPU-Architektur in eine andere übersetzt.

JIT Java kompilieren

Diese Arten von Compilern haben bessere Leistung als Dolmetscher , da sie, anstatt den gesamten Code zu interpretieren, kompilieren, was sie brauchen, wie sie es brauchen. Das Kompilieren des Codes zur Laufzeit wirkt sich jedoch mehr oder weniger auf die Leistung aus, verglichen mit der Verwendung eines Standard-Compilers, der die Binärdatei generiert und es uns ermöglicht, sie direkt auf dem Computer auszuführen. Und je umfangreicher das Programm ist, das wir ausführen möchten, desto größer ist die Auswirkung auf die Leistung. Dies führt dazu, dass einige sehr große Programme bis zu einer Minute brauchen, um die ersten paar Funktionen auszuführen.

Um diese Auswirkungen zu reduzieren, gibt es einige Pre-Compiler , sowie Microsoft's nativer Bildgenerator (Ngen) , die dafür sorgen, dass die Ausführungszeit eliminiert wird und der JIT-Compiler von Anfang an funktioniert.

Da die Just-In-Time-Kompilierung in erster Linie ausführbare Daten verwendet, sind diese außerdem vor potenzielle Exploits ist eine große Herausforderung für Entwickler. Der Speicher muss genau überwacht und mit fortschrittlichen Sicherheitstechniken wie Isolation geschützt werden, um unnötige Risiken zu vermeiden.

Optimieren Sie den JIT-Compiler (Just-In-Time)

Je nach Compilertyp, den wir verwenden, können verschiedene Stufen der Codeoptimierung gefunden werden. Zum Beispiel bei OpenJ9 (Eclipse JIT-Compiler für Java-Code ) ist es möglich, den gewünschten Grad der Codeoptimierung auszuwählen. Je höher die Optimierung des Just-In-Time-Compilers, desto schneller wird der Code auf unserem Computer ausgeführt, natürlich auf Kosten eines viel höheren Verbrauchs von RAM und CPU.

Darüber hinaus sind diese Compiler darauf ausgelegt, die Funktionen eines Programms zu analysieren und zu verfolgen und festzustellen, welche am häufigsten wiederholt werden. Daher werden auf sie bestimmte Optimierungen angewendet, und welche werden am wenigsten genannt, sodass sie ein wenig im Hintergrund bleiben, um unnötigen Ressourcenverbrauch zu vermeiden.