Es gibt ein paar Dinge, die den C++ Compiler langsamer als die von Java/C# machen. Die Grammatik ist viel komplexer, die generische Programmierunterstützung ist in C++ viel leistungsfähiger, aber gleichzeitig ist die Kompilierung teurer. Die Aufnahme von Dateien funktioniert anders als der Import von Modulen.
Inclussion von Header-Dateien
Zuerst, wenn Sie eine Datei in C++, den Inhalt der Datei enthalten (.h in der Regel) in der aktuellen Übersetzungseinheit injiziert werden (einschließlich Wache derselben Header zweimal vermeiden Reinjezierung) und das ist transitiv. Das heißt, wenn Sie Header a.h einschließen, der wiederum b.h enthält, fügt Ihre Kompilierungseinheit den gesamten Code in a ein.h und alle Code in b.h.
Java (oder C#, ich werde über Java sprechen, aber sie sind in dieser ähnlich) haben keine Include-Dateien, sie hängen von den Binaries aus der Kompilation der verwendeten Klassen ab. Das bedeutet, dass Sie beim Kompilieren von a.java, das ein in b.java definiertes Objekt B verwendet, nur die binäre b.class-Klasse überprüfen. Sie müssen nicht tiefer gehen, um die Abhängigkeiten von B zu überprüfen, damit der Prozess früher beendet werden kann (mit nur einer Überprüfungsebene).
Gleichzeitig enthält das Einschließen von Dateien nur die Sprachdefinitionen und die Verarbeitung benötigt Zeit. Wenn der Java/C# -Compiler eine Binärdatei liest, hat er die gleiche Information, wird aber bereits vom Kompilierungsschritt verarbeitet, der ihn generiert hat.
Also am Ende, in C/C++ mehr Dateien enthalten sind und zur gleichen Zeit ist die Verarbeitung dieser Includes teurer als die Verarbeitung von binären Modulen.
Vorlagen
Vorlagen sind speziell auf ihre eigene Weise. Sie können vorkompiliert werden, aber sie sind normalerweise nicht (aus einer guten Reihe von Gründen). Dies bedeutet, dass in allen Kompilierungseinheiten, die std :: vector verwenden, die gesamte Menge der verwendeten Vektormethoden (nicht verwendete Template-Methoden werden nicht kompiliert) verarbeitet und der vom Compiler erzeugte Binärcode verarbeitet wird. In einem späteren Schritt werden während der Verknüpfung redundante Definitionen der gleichen Methode gelöscht, aber während der Kompilierung müssen sie verarbeitet werden.
Die Unterstützung in Java für Generika ist in vielerlei Hinsicht begrenzter. Am Ende gibt es zum Beispiel nur eine Vector-Klassen-Binärdatei, und wenn der Compiler Vector in Java sieht, generiert er Code-Prüfcode, bevor er an die echte Vector-Implementierung delegiert (die Plain-Objekte speichert), und das ist nicht generisch. Der Compiler stellt zwar die Typgarantien bereit, kompiliert jedoch für jeden Typ keinen Vektor.
In C# ist es wieder einmal anders. Die C# Unterstützung für Generics ist komplexer als die von Java, und am Ende unterscheiden sich generische Klassen von einfachen Klassen, aber sie werden nur einmal kompiliert, da das binäre Format alle erforderlichen Informationen enthält.
Was vergleichen Sie? Die Zeit, die benötigt wird, um eine Anwendung aus der Quelle oder die Laufzeitleistung zu kompilieren? –
Könnte mit einigen Beispielen interessanter sein. Einige Messungen mit Timings + Anzahl der Codezeilen. –
Ich vergleiche die Kompilierungszeit, nicht die Laufzeit. – Lawand