20 Stimmen

Wann ist Java schneller als C++ (oder wann ist JIT schneller als vorkompiliert)?

Mögliches Duplikat:
JIT-Compiler gegenüber Offline-Compilern

Ich habe gehört, dass Java-Programme oder vielmehr Teile von Java-Programmen unter bestimmten Umständen aufgrund von JIT-Optimierungen schneller ausgeführt werden können als der "gleiche" Code in C++ (oder anderer vorkompilierter Code). Dies ist darauf zurückzuführen, dass der Compiler in der Lage ist, den Geltungsbereich einiger Variablen zu bestimmen, einige Konditionale zu vermeiden und ähnliche Tricks zur Laufzeit anzuwenden.

Könnten Sie ein (oder besser einige) Beispiele nennen, auf die dies zutrifft? Und vielleicht die genauen Bedingungen umreißen, unter denen der Compiler in der Lage ist, den Bytecode über das hinaus zu optimieren, was mit vorkompiliertem Code möglich ist?

ANMERKUNG : Diese Frage ist no über den Vergleich von Java mit C++. Es geht um die Möglichkeiten der JIT-Kompilierung. Bitte kein Flaming. Ich bin mir auch nicht bewusst, dass es Duplikate gibt. Bitte weisen Sie darauf hin, wenn Sie welche finden.

40voto

Rex Kerr Punkte 164629

In der Praxis werden Sie wahrscheinlich feststellen, dass Ihr naiv geschriebener Java-Code Ihren naiv geschriebenen C++-Code in diesen Situationen übertrifft (die ich alle persönlich beobachtet habe):

  • Viele kleine Speicherzuweisungen/Deallokationen. Die großen JVMs verfügen über äußerst effiziente Speichersubsysteme, und die Garbage Collection kann effizienter sein als das explizite Freigeben (außerdem kann sie Speicheradressen und dergleichen verschieben, wenn sie es wirklich will).

  • Effizienter Zugriff durch tiefe Hierarchien von Methodenaufrufen. Die JVM ist sehr gut darin, alles, was nicht notwendig ist, zu eliminieren, meiner Erfahrung nach besser als die meisten C++-Compiler (einschließlich gcc und icc). Dies liegt zum Teil daran, dass sie zur Laufzeit eine dynamische Analyse durchführen kann (d. h. sie kann überoptimieren und nur dann deoptimieren, wenn sie ein Problem entdeckt).

  • Kapselung der Funktionalität in kleinen, kurzlebigen Objekten.

In jedem Fall kann C++ besser sein, wenn man sich die Mühe macht (zwischen freien Listen und blockweise zugewiesenem/freigegebenem Speicher kann C++ das JVM-Speichersystem in fast jedem spezifischen Fall schlagen; mit zusätzlichem Code, Schablonen und cleveren Makros kann man Aufrufstapel sehr effektiv kollabieren; und man kann kleine, teilweise initialisierte, stapelweise zugewiesene Objekte in C++ haben, die das kurzlebige Objektmodell der JVM übertreffen). Aber Sie wollen sich wahrscheinlich nicht die Mühe machen.

6voto

Michael Borgwardt Punkte 334642

Einige Beispiele:

  • Der JIT-Compiler kann sehr CPU-spezifischen Maschinencode erzeugen, indem er z. B. die neuesten SSE-Erweiterungen verwendet, die man in vorkompiliertem Code, der auf einer Vielzahl von CPUs laufen muss, nicht verwenden würde.
  • Das JIT weiß, wenn eine virtuelle Methode (der Standard in Java) nirgendwo überschrieben wird, und kann daher inlined werden (dies erfordert jedoch die Fähigkeit, das Inline-Verfahren aufzuheben, wenn eine neue Klasse geladen wird, die die Methode überschreibt; aktuelle Java-JIT-Compiler tun dies tatsächlich).
  • Diesbezüglich, Fluchtanalyse ermöglicht mehrere situationsbedingte Optimierungen.

5voto

Bert F Punkte 81431

Wikipedia: http://en.wikipedia.org/wiki/Just-in-time_compilation#Overview

Darüber hinaus kann es in einigen Fällen bieten eine bessere Leistung als die statische Kompilierung als viele Optimierungen sind nur während der Laufzeit durchführbar :

  1. Die Zusammenstellung kann sein optimiert auf die Ziel-CPU und das Betriebssystemmodell wo die Anwendung läuft. So kann JIT beispielsweise SSE2-CPU-Anweisungen auswählen, wenn es feststellt, dass die CPU diese unterstützt. Um dieses Maß an Optimierungsspezifität mit einem statischen Compiler zu erreichen, muss man entweder eine Binärdatei für jede vorgesehene Plattform/Architektur kompilieren oder mehrere Versionen von Teilen des Codes in eine einzige Binärdatei aufnehmen.

  2. Das System ist in der Lage Statistiken sammeln darüber, wie das Programm in der jeweiligen Umgebung tatsächlich abläuft, und es kann Neuanordnung und Neukompilierung für optimale Leistung . Einige statische Compiler können jedoch auch Profilinformationen als Eingabe verwenden.

  3. Das System kann globale Code-Optimierungen (z.B. Inlining von Bibliotheksfunktionen), ohne die Vorteile des dynamischen Linkens zu verlieren und ohne den mit statischen Compilern und Linkern verbundenen Overhead. Insbesondere bei globalen Inline-Substitutionen wird ein statischer Kompilierungsprozess kann Laufzeitprüfungen erfordern und sicherstellen, dass ein virtueller Aufruf erfolgt, wenn die tatsächliche Klasse des Objekts die Inline-Methode überschreibt, und dass Randbedingungsprüfungen bei Array-Zugriffen möglicherweise in Schleifen verarbeitet werden müssen. Bei der Just-in-Time-Kompilierung wird in vielen Fällen diese Verarbeitung kann aus den Schleifen herausgelöst werden, was oft zu einer erheblichen Geschwindigkeitssteigerung führt .

  4. Obwohl dies bei statisch kompilierten Garbage-Collected-Sprachen möglich ist, kann ein Bytecode-System leichter Neuanordnung von ausgeführtem Code zur besseren Nutzung des Cache .

0voto

Codo Punkte 70076

Die Speicherverwaltung von Java ist wesentlich schneller als die von C++. Siehe Java Theorie und Praxis: Urbane Leistungslegenden, revisited .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X