Warum dauert die C ++ - Kompilierung so lange?

540

Das Kompilieren einer C ++ - Datei dauert im Vergleich zu C # und Java sehr lange. Das Kompilieren einer C ++ - Datei dauert erheblich länger als das Ausführen eines Python-Skripts normaler Größe. Ich verwende derzeit VC ++, aber es ist das gleiche mit jedem Compiler. Warum ist das?

Die beiden Gründe, an die ich denken konnte, waren das Laden von Header-Dateien und das Ausführen des Präprozessors, aber das scheint nicht zu erklären, warum es so lange dauert.

Dan Goldstein
quelle
58
VC ++ unterstützt vorkompilierte Header. Ihre Verwendung wird helfen. Viel.
Brian
1
Ja in meinem Fall (meistens C mit ein paar Klassen - keine Vorlagen) beschleunigen vorkompilierte Header ungefähr 10x
Lothar
@ Brian Ich würde nie einen vorkompilierten Kopf in einer Bibliothek verwenden
Cole Johnson
13
It takes significantly longer to compile a C++ file- Meinst du 2 Sekunden im Vergleich zu 1 Sekunde? Das ist zwar doppelt so lang, aber kaum von Bedeutung. Oder meinst du 10 Minuten im Vergleich zu 5 Sekunden? Bitte quantifizieren.
Nick Gammon
2
Ich setze auf Module; Ich erwarte nicht, dass C ++ - Projekte schneller erstellt werden können als in anderen Programmiersprachen, nur mit Modulen, aber es kann für die meisten Projekte mit etwas Management sehr nahe kommen. Ich hoffe, nach den Modulen einen guten Paketmanager mit künstlicher Integration zu sehen
Abdurrahim

Antworten:

800

Mehrere Gründe

Header-Dateien

Für jede einzelne Kompilierungseinheit müssen Hunderte oder sogar Tausende von Headern (1) geladen und (2) kompiliert werden. Jeder von ihnen hat in der Regel für jede Übersetzungseinheit neu kompiliert werden, da die Prä - Prozessor sorgt dafür , dass das Ergebnis eine Kopfzusammenstellung kann zwischen jeder Übersetzungseinheit variieren. (Ein Makro kann in einer Kompilierungseinheit definiert werden, die den Inhalt des Headers ändert.)

Dies ist wahrscheinlich der Hauptgrund, da für jede Kompilierungseinheit große Mengen an Code kompiliert werden müssen und außerdem jeder Header mehrmals kompiliert werden muss (einmal für jede Kompilierungseinheit, die ihn enthält).

Verknüpfen

Nach dem Kompilieren müssen alle Objektdateien miteinander verknüpft werden. Dies ist im Grunde ein monolithischer Prozess, der nicht sehr gut parallelisiert werden kann und Ihr gesamtes Projekt verarbeiten muss.

Parsing

Die Syntax ist äußerst kompliziert zu analysieren, hängt stark vom Kontext ab und ist sehr schwer zu unterscheiden. Das braucht viel Zeit.

Vorlagen

In C # List<T>ist der einzige Typ, der kompiliert wird, unabhängig davon, wie viele Instanzen von List Sie in Ihrem Programm haben. In C ++ vector<int>ist ein völlig separater Typ von vector<float>, und jeder muss separat kompiliert werden.

Hinzu kommt, dass Vorlagen eine vollständige Turing-vollständige "Subsprache" bilden, die der Compiler interpretieren muss, und dies kann lächerlich kompliziert werden. Selbst relativ einfacher Metaprogrammiercode für Vorlagen kann rekursive Vorlagen definieren, die Dutzende und Dutzende von Vorlageninstanziierungen erstellen. Vorlagen können auch zu äußerst komplexen Typen mit lächerlich langen Namen führen, die dem Linker viel zusätzliche Arbeit hinzufügen. (Es müssen viele Symbolnamen verglichen werden, und wenn diese Namen zu vielen tausend Zeichen werden können, kann dies ziemlich teuer werden.)

Und natürlich verschärfen sie die Probleme mit Header-Dateien, da Vorlagen im Allgemeinen in Headern definiert werden müssen, was bedeutet, dass für jede Kompilierungseinheit viel mehr Code analysiert und kompiliert werden muss. Im einfachen C-Code enthält ein Header normalerweise nur Vorwärtsdeklarationen, aber nur sehr wenig tatsächlichen Code. In C ++ ist es nicht ungewöhnlich, dass sich fast der gesamte Code in Header-Dateien befindet.

Optimierung

C ++ ermöglicht einige sehr dramatische Optimierungen. Mit C # oder Java können Klassen nicht vollständig eliminiert werden (sie müssen zu Reflexionszwecken vorhanden sein), aber selbst ein einfaches C ++ - Vorlagen-Metaprogramm kann leicht Dutzende oder Hunderte von Klassen generieren, die alle in der Optimierung inline und wieder eliminiert werden Phase.

Darüber hinaus muss ein C ++ - Programm vom Compiler vollständig optimiert werden. Das AC # -Programm kann sich darauf verlassen, dass der JIT-Compiler beim Laden zusätzliche Optimierungen durchführt. C ++ erhält keine solchen "zweiten Chancen". Was der Compiler generiert, ist so optimiert wie es nur geht.

Maschine

C ++ wird zu Maschinencode kompiliert, der möglicherweise etwas komplizierter ist als der von Java oder .NET verwendete Bytecode (insbesondere im Fall von x86). (Dies wird nur der Vollständigkeit halber erwähnt, weil es in Kommentaren und dergleichen erwähnt wurde. In der Praxis ist es unwahrscheinlich, dass dieser Schritt mehr als einen winzigen Bruchteil der gesamten Kompilierungszeit in Anspruch nimmt.)

Fazit

Die meisten dieser Faktoren werden von C-Code gemeinsam genutzt, der tatsächlich ziemlich effizient kompiliert wird. Der Parsing-Schritt ist in C ++ viel komplizierter und kann erheblich mehr Zeit in Anspruch nehmen, aber der Haupttäter sind wahrscheinlich Vorlagen. Sie sind nützlich und machen C ++ zu einer weitaus leistungsfähigeren Sprache, aber sie fordern auch ihren Tribut in Bezug auf die Kompilierungsgeschwindigkeit.

jalf
quelle
38
Zu Punkt 3: Die C-Kompilierung ist deutlich schneller als C ++. Es ist definitiv das Frontend, das die Verlangsamung verursacht, und nicht die Codegenerierung.
Tom
72
In Bezug auf Vorlagen: Nicht nur Vektor <int> muss getrennt von Vektor <double> kompiliert werden, sondern Vektor <int> wird in jeder Kompilierungseinheit, die ihn verwendet, neu kompiliert. Redundante Definitionen werden vom Linker entfernt.
David Rodríguez - Dribeas
15
dribeas: Stimmt, aber das ist nicht spezifisch für Vorlagen. Inline-Funktionen oder andere in Headern definierte Funktionen werden überall dort neu kompiliert, wo sie enthalten sind. Aber ja, das ist besonders schmerzhaft bei Vorlagen. :)
Jalf
15
@configurator: Visual Studio und gcc ermöglichen vorkompilierte Header, was die Kompilierung erheblich beschleunigen kann.
small_duck
5
Ich bin mir nicht sicher, ob die Optimierung das Problem ist, da unsere DEBUG-Builds tatsächlich langsamer sind als die Builds im Release-Modus. Die pdb-Generation ist auch ein Schuldiger.
Gast128
40

Die Verlangsamung ist bei keinem Compiler unbedingt gleich.

Ich habe weder Delphi noch Kylix verwendet, aber in den MS-DOS-Tagen wurde ein Turbo Pascal-Programm fast sofort kompiliert, während das entsprechende Turbo C ++ - Programm nur crawlt.

Die beiden Hauptunterschiede waren ein sehr starkes Modulsystem und eine Syntax, die eine Kompilierung in einem Durchgang ermöglichte.

Es ist sicher möglich, dass die Kompilierungsgeschwindigkeit für C ++ - Compilerentwickler keine Priorität hatte, aber es gibt auch einige inhärente Komplikationen in der C / C ++ - Syntax, die die Verarbeitung erschweren. (Ich bin kein Experte für C, aber Walter Bright ist es. Nachdem er verschiedene kommerzielle C / C ++ - Compiler erstellt hat, hat er die D-Sprache erstellt. Eine seiner Änderungen bestand darin, eine kontextfreie Grammatik zu erzwingen, um das Parsen der Sprache zu vereinfachen .)

Außerdem werden Sie feststellen, dass Makefiles im Allgemeinen so eingerichtet sind, dass jede Datei separat in C kompiliert wird. Wenn also 10 Quelldateien dieselbe Include-Datei verwenden, wird diese Include-Datei zehnmal verarbeitet.

Tangentensturm
quelle
38
Es ist interessant, Pascal zu vergleichen, da Niklaus Wirth die Zeit nutzte, die der Compiler brauchte, um sich selbst als Benchmark beim Entwerfen seiner Sprachen und Compiler zu kompilieren. Es gibt eine Geschichte, nach der er ein Modul für die schnelle Symbolsuche sorgfältig geschrieben und durch eine einfache lineare Suche ersetzt hat, da der Compiler aufgrund der reduzierten Codegröße schneller selbst kompiliert wurde.
Dietrich Epp
1
@DietrichEpp Empirismus zahlt sich aus.
Tomas Zubiri
39

Parsing und Codegenerierung sind eigentlich ziemlich schnell. Das eigentliche Problem ist das Öffnen und Schließen von Dateien. Denken Sie daran, dass der Compiler auch mit Include-Wachen die .H-Datei geöffnet und jede Zeile gelesen hat (und sie dann ignoriert).

Ein Freund nahm einmal (während er sich bei der Arbeit langweilte) die Bewerbung seines Unternehmens und legte alles - alle Quell- und Header-Dateien - in eine große Datei. Die Kompilierungszeit wurde von 3 Stunden auf 7 Minuten gesenkt.

James Curran
quelle
14
Nun, der Dateizugriff hat sicherlich eine Hand dabei, aber wie Jalf sagte, wird der Hauptgrund dafür etwas anderes sein, nämlich das wiederholte Parsen vieler, vieler, vieler (verschachtelter!) Header-Dateien, die in Ihrem Fall vollständig ausfallen.
Konrad Rudolph
9
An diesem Punkt muss Ihr Freund vorkompilierte Header einrichten, Abhängigkeiten zwischen verschiedenen Header-Dateien aufheben (versuchen Sie, einen Header einschließlich eines anderen zu vermeiden, stattdessen vorwärts zu deklarieren) und eine schnellere Festplatte erhalten. Davon abgesehen eine ziemlich erstaunliche Metrik.
Tom Leys
6
Befindet sich die gesamte Header-Datei (mit Ausnahme möglicher Kommentare und Leerzeilen) innerhalb der Header-Schutzfunktionen, kann sich gcc die Datei merken und überspringen, wenn das richtige Symbol definiert ist.
CesarB
11
Parsen ist eine große Sache. Für N Paare von Quell- / Header-Dateien ähnlicher Größe mit Abhängigkeiten gibt es O (N ^ 2) Durchgänge durch Header-Dateien. Wenn Sie den gesamten Text in eine einzelne Datei einfügen, wird das doppelte Parsen reduziert.
Tom
9
Kleine Randnotiz: Die Include-Schutzvorrichtungen schützen vor mehreren Analysen pro Kompilierungseinheit. Nicht gegen mehrere Parsen insgesamt.
Marco van de Voort
16

Ein weiterer Grund ist die Verwendung des C-Vorprozessors zum Auffinden von Deklarationen. Selbst mit Header-Wachen muss .h jedes Mal, wenn sie enthalten sind, immer wieder analysiert werden. Einige Compiler unterstützen vorkompilierte Header, die dabei helfen können, werden jedoch nicht immer verwendet.

Siehe auch: Häufig gestellte C ++ - Antworten

Dave Ray
quelle
Ich denke, Sie sollten den Kommentar zu vorkompilierten Headern fett schreiben, um auf diesen WICHTIGEN Teil Ihrer Antwort hinzuweisen.
Kevin
6
Befindet sich die gesamte Header-Datei (mit Ausnahme möglicher Kommentare und Leerzeilen) innerhalb der Header-Schutzfunktionen, kann sich gcc die Datei merken und überspringen, wenn das richtige Symbol definiert ist.
CesarB
5
@CesarB: Es muss noch einmal vollständig pro Kompilierungseinheit (CPP-Datei) vollständig verarbeitet werden.
Sam Harwell
16

C ++ wird in Maschinencode kompiliert. Sie haben also den Vorprozessor, den Compiler, den Optimierer und schließlich den Assembler, die alle ausgeführt werden müssen.

Java und C # werden vor der Ausführung in Bytecode / IL kompiliert, und die Java Virtual Machine / .NET Framework wird vor der Ausführung ausgeführt (oder JIT wird in Maschinencode kompiliert).

Python ist eine interpretierte Sprache, die auch in Bytecode kompiliert wird.

Ich bin mir sicher, dass es auch andere Gründe dafür gibt, aber im Allgemeinen spart es Zeit, nicht in die native Maschinensprache kompilieren zu müssen.

Alan
quelle
15
Die durch die Vorverarbeitung hinzugefügten Kosten sind trivial. Der Haupt- "andere Grund" für eine Verlangsamung ist, dass die Kompilierung in separate Aufgaben aufgeteilt wird (eine pro Objektdatei), sodass allgemeine Header immer wieder verarbeitet werden. Das ist O (N ^ 2) Worst-Case im Vergleich zu den meisten anderen Sprachen O (N) Parsing-Zeit.
Tom
12
Aus derselben Argumentation könnte man erkennen, dass C-, Pascal- usw. Compiler langsam sind, was im Durchschnitt nicht der Fall ist. Es hat mehr mit der Grammatik von C ++ und dem riesigen Zustand zu tun, den ein C ++ - Compiler aufrechterhalten muss.
Sebastian Mach
2
C ist langsam. Es hat das gleiche Problem beim Parsen von Headern wie die akzeptierte Lösung. Nehmen Sie beispielsweise ein einfaches Windows-GUI-Programm, das windows.h in einigen Kompilierungseinheiten enthält, und messen Sie die Kompilierungsleistung, wenn Sie (kurze) Kompilierungseinheiten hinzufügen.
Marco van de Voort
13

Die größten Probleme sind:

1) Die unendliche Header-Wiederholung. Schon erwähnt. Schadensbegrenzungen (wie #pragma einmal) funktionieren normalerweise nur pro Kompilierungseinheit, nicht pro Build.

2) Die Tatsache, dass die Toolchain häufig in mehrere Binärdateien unterteilt ist (make, Präprozessor, Compiler, Assembler, Archiver, impdef, Linker und dlltool im Extremfall), die alle bei jedem Aufruf den Status neu initialisieren und neu laden müssen ( Compiler, Assembler) oder alle paar Dateien (Archivierer, Linker und DLL-Tool).

Siehe auch diese Diskussion zu comp.compilers: http://compilers.iecc.com/comparch/article/03-11-078 speziell diese:

http://compilers.iecc.com/comparch/article/02-07-128

Beachten Sie, dass John, der Moderator von comp.compilers, zuzustimmen scheint und dass dies bedeutet, dass es möglich sein sollte, ähnliche Geschwindigkeiten auch für C zu erreichen, wenn man die Toolchain vollständig integriert und vorkompilierte Header implementiert. Viele kommerzielle C-Compiler tun dies bis zu einem gewissen Grad.

Beachten Sie, dass das Unix-Modell, bei dem alles in eine separate Binärdatei zerlegt wird, eine Art Worst-Case-Modell für Windows ist (mit seiner langsamen Prozesserstellung). Dies ist beim Vergleich der GCC-Erstellungszeiten zwischen Windows und * nix sehr auffällig, insbesondere wenn das make / configure-System auch einige Programme aufruft, um Informationen zu erhalten.

Marco van de Voort
quelle
12

Erstellen von C / C ++: Was passiert wirklich und warum dauert es so lange?

Ein relativ großer Teil der Softwareentwicklungszeit wird nicht für das Schreiben, Ausführen, Debuggen oder sogar Entwerfen von Code aufgewendet, sondern darauf gewartet, dass der Kompilierungsvorgang abgeschlossen ist. Um die Dinge schnell zu machen, müssen wir zuerst verstehen, was passiert, wenn C / C ++ - Software kompiliert wird. Die Schritte sind ungefähr wie folgt:

  • Aufbau
  • Tool starten
  • Abhängigkeitsprüfung
  • Zusammenstellung
  • Verknüpfen

Wir werden uns nun jeden Schritt genauer ansehen und uns darauf konzentrieren, wie sie schneller gemacht werden können.

Aufbau

Dies ist der erste Schritt beim Erstellen. Normalerweise bedeutet dies, ein Konfigurationsskript oder CMake, Gyp, SCons oder ein anderes Tool auszuführen. Dies kann bei sehr großen Autotools-basierten Konfigurationsskripten zwischen einer Sekunde und mehreren Minuten dauern.

Dieser Schritt kommt relativ selten vor. Es muss nur ausgeführt werden, wenn Konfigurationen oder Build-Konfigurationen geändert werden. Ohne die Änderung der Build-Systeme muss nicht viel getan werden, um diesen Schritt zu beschleunigen.

Tool starten

Dies passiert, wenn Sie make ausführen oder auf das Build-Symbol einer IDE klicken (was normalerweise ein Alias ​​für make ist). Die Binärdatei des Build-Tools startet und liest die Konfigurationsdateien sowie die Build-Konfiguration, die normalerweise identisch sind.

Je nach Komplexität und Größe des Builds kann dies zwischen einem Bruchteil einer Sekunde und mehreren Sekunden dauern. An sich wäre das nicht so schlimm. Leider führen die meisten make-basierten Build-Systeme dazu, dass make für jeden einzelnen Build zehn- bis hundertmal aufgerufen wird. Normalerweise wird dies durch die rekursive Verwendung von make verursacht (was schlecht ist).

Es sollte beachtet werden, dass der Grund, warum Make so langsam ist, kein Implementierungsfehler ist. Die Syntax von Makefiles hat einige Macken, die eine wirklich schnelle Implementierung so gut wie unmöglich machen. Dieses Problem macht sich in Kombination mit dem nächsten Schritt noch deutlicher bemerkbar.

Abhängigkeitsprüfung

Sobald das Build-Tool seine Konfiguration gelesen hat, muss es feststellen, welche Dateien geändert wurden und welche neu kompiliert werden müssen. Die Konfigurationsdateien enthalten ein gerichtetes azyklisches Diagramm, das die Build-Abhängigkeiten beschreibt. Dieses Diagramm wird normalerweise während des Konfigurationsschritts erstellt. Die Startzeit des Build-Tools und der Abhängigkeitsscanner werden bei jedem einzelnen Build ausgeführt. Ihre kombinierte Laufzeit bestimmt die Untergrenze des Edit-Compile-Debug-Zyklus. Bei kleinen Projekten beträgt diese Zeit normalerweise einige Sekunden. Das ist erträglich. Es gibt Alternativen zu Make. Der schnellste von ihnen ist Ninja, der von Google-Ingenieuren für Chromium entwickelt wurde. Wenn Sie CMake oder Gyp zum Erstellen verwenden, wechseln Sie einfach zu den Ninja-Backends. Sie müssen nichts an den Build-Dateien selbst ändern, sondern nur den Geschwindigkeitsschub genießen. Ninja ist jedoch auf den meisten Distributionen nicht enthalten.

Zusammenstellung

An dieser Stelle rufen wir endlich den Compiler auf. Hier sind die ungefähren Schritte aufgeführt.

  • Zusammenführen umfasst
  • Code analysieren
  • Codegenerierung / -optimierung

Entgegen der landläufigen Meinung ist das Kompilieren von C ++ nicht allzu langsam. Die STL ist langsam und die meisten Build-Tools zum Kompilieren von C ++ sind langsam. Es gibt jedoch schnellere Tools und Möglichkeiten, um die langsamen Teile der Sprache zu mildern.

Die Verwendung erfordert etwas Ellbogenfett, aber die Vorteile sind unbestreitbar. Schnellere Erstellungszeiten führen zu glücklicheren Entwicklern, mehr Flexibilität und schließlich zu besserem Code.

Ravindra Acharya
quelle
9

Eine kompilierte Sprache erfordert immer einen höheren anfänglichen Aufwand als eine interpretierte Sprache. Außerdem haben Sie Ihren C ++ - Code möglicherweise nicht sehr gut strukturiert. Zum Beispiel:

#include "BigClass.h"

class SmallClass
{
   BigClass m_bigClass;
}

Kompiliert viel langsamer als:

class BigClass;

class SmallClass
{
   BigClass* m_bigClass;
}
Andy Brice
quelle
3
Dies gilt insbesondere dann, wenn BigClass 5 weitere Dateien enthält, die es verwendet, und schließlich den gesamten Code in Ihrem Programm enthält.
Tom Leys
7
Dies ist vielleicht ein Grund. Aber Pascal zum Beispiel benötigt nur ein Zehntel der Kompilierungszeit, die ein gleichwertiges C ++ - Programm benötigt. Dies liegt nicht daran, dass die Optimierung von gcc: s länger dauert, sondern daran, dass Pascal einfacher zu analysieren ist und sich nicht mit einem Präprozessor befassen muss. Siehe auch Digital Mars D Compiler.
Daniel O
2
Es ist nicht das einfachere Parsen, sondern die Modularität, die es vermeidet, Windows.h und unzählige andere Header für jede Kompilierungseinheit neu zu interpretieren. Ja, Pascal analysiert leichter (obwohl reife wie Delphi wieder komplizierter sind), aber das macht nicht den großen Unterschied.
Marco van de Voort
1
Die hier gezeigte Technik, die eine Verbesserung der Kompilierungsgeschwindigkeit bietet, wird als Vorwärtsdeklaration bezeichnet .
DavidRR
Schreiben von Klassen in nur einer Datei. Wäre es nicht chaotischer Code?
Fennekin
7

Eine einfache Möglichkeit, die Kompilierungszeit in größeren C ++ - Projekten zu verkürzen, besteht darin, eine * .cpp-Include-Datei zu erstellen, die alle cpp-Dateien in Ihrem Projekt enthält, und diese zu kompilieren. Dies reduziert das Problem der Header-Explosion auf einmal. Dies hat den Vorteil, dass Kompilierungsfehler weiterhin auf die richtige Datei verweisen.

Angenommen, Sie haben a.cpp, b.cpp und c.cpp. Erstellen Sie eine Datei: Everything.cpp:

#include "a.cpp"
#include "b.cpp"
#include "c.cpp"

Kompilieren Sie dann das Projekt, indem Sie einfach alles erstellen

Rileyberton
quelle
3
Ich sehe den Einwand gegen diese Methode nicht. Angenommen, Sie generieren die Includes aus einem Skript oder Makefile, handelt es sich nicht um ein Wartungsproblem. Tatsächlich beschleunigt es die Kompilierung, ohne Kompilierungsprobleme zu verschleiern. Sie könnten den Speicherverbrauch beim Kompilieren argumentieren, aber das ist auf modernen Maschinen selten ein Problem. Was ist der Gegenstand dieses Ansatzes (abgesehen von der Behauptung, dass er falsch ist)?
Rileyberton
9
@rileyberton (da jemand Ihren Kommentar positiv bewertet hat) lassen Sie mich das formulieren: Nein, es beschleunigt die Kompilierung nicht. Tatsächlich wird sichergestellt, dass jede Kompilierung die maximale Zeit in Anspruch nimmt, indem keine Übersetzungseinheiten isoliert werden. Das Tolle an ihnen ist, dass Sie nicht alle .cpp-s neu kompilieren müssen, wenn sie sich nicht geändert haben. (Das ignoriert stilistische Argumente). Richtiges Abhängigkeitsmanagement und möglicherweise vorkompilierte Header sind viel besser.
sehe
7
Entschuldigung, aber dies kann eine sehr effiziente Methode sein, um die Kompilierung zu beschleunigen, da Sie (1) die Verknüpfung so gut wie eliminieren und (2) häufig verwendete Header nur einmal verarbeiten müssen. Es funktioniert auch in der Praxis , wenn Sie sich die Mühe machen, es zu versuchen. Leider macht es inkrementelle Neuerstellungen unmöglich, so dass jeder Build komplett von Grund auf neu ist. Aber eine vollständige Wiederherstellung mit dieser Methode ist viel schneller als das, was Sie sonst bekommen würden
Jalf
4
@BartekBanachewicz sicher, aber was Sie sagten, war, dass "es die Kompilierung nicht beschleunigt", ohne Qualifikation. Wie Sie sagten, nimmt jede Kompilierung die maximale Zeit in Anspruch (keine teilweisen Neuerstellungen), reduziert aber gleichzeitig das Maximum im Vergleich zu dem, was es sonst wäre, drastisch. Ich sage nur, es ist ein bisschen nuancierter als "
Tu
2
Viel Spaß mit statischen Variablen und Funktionen. Wenn ich eine große Kompilierungseinheit möchte, erstelle ich eine große CPP-Datei.
Gnasher729
6

Einige Gründe sind:

1) Die C ++ - Grammatik ist komplexer als C # oder Java und benötigt mehr Zeit zum Parsen.

2) (Wichtiger) Der C ++ - Compiler erzeugt Maschinencode und führt alle Optimierungen während der Kompilierung durch. C # und Java gehen nur den halben Weg und überlassen diese Schritte JIT.

Nemanja Trifunovic
quelle
5

Der Nachteil ist, dass das Programm etwas schneller läuft. Das mag für Sie während der Entwicklung ein kalter Trost sein, aber es kann sehr wichtig sein, wenn die Entwicklung abgeschlossen ist und das Programm nur von Benutzern ausgeführt wird.

TED
quelle
3

Die meisten Antworten sind etwas unklar, wenn erwähnt wird, dass C # aufgrund der Kosten für die Ausführung von Aktionen, die in C ++ nur einmal zur Kompilierungszeit ausgeführt werden, immer langsamer ausgeführt wird. Diese Leistungskosten werden auch durch Laufzeitabhängigkeiten beeinflusst (mehr Dinge müssen geladen werden, um in der Lage zu sein zu laufen), ganz zu schweigen davon, dass C # -Programme immer einen höheren Speicherbedarf haben, was dazu führt, dass die Leistung enger mit der Fähigkeit der verfügbaren Hardware zusammenhängt. Gleiches gilt für andere Sprachen, die interpretiert werden oder von einer VM abhängen.

Panik
quelle
3

Ich kann mir zwei Probleme vorstellen, die sich auf die Geschwindigkeit auswirken können, mit der Ihre Programme in C ++ kompiliert werden.

MÖGLICHE AUSGABE 1 - KOMPILIEREN DES HEADERS: (Dies wurde möglicherweise bereits durch eine andere Antwort oder einen anderen Kommentar behoben .) Microsoft Visual C ++ (AKA VC ++) unterstützt vorkompilierte Header, die ich sehr empfehle. Wenn Sie ein neues Projekt erstellen und den von Ihnen erstellten Programmtyp auswählen, sollte ein Fenster des Setup-Assistenten auf Ihrem Bildschirm angezeigt werden. Wenn Sie unten auf die Schaltfläche "Weiter>" klicken, gelangen Sie im Fenster zu einer Seite mit mehreren Funktionslisten. Stellen Sie sicher, dass das Kontrollkästchen neben der Option "Vorkompilierter Header" aktiviert ist. (HINWEIS: Dies war meine Erfahrung mit Win32-Konsolenanwendungen in C ++, dies ist jedoch möglicherweise nicht bei allen Arten von Programmen in C ++ der Fall.)

MÖGLICHE AUSGABE 2 - DER ORT, AN DEN ERSTELLT WIRD: In diesem Sommer nahm ich an einem Programmierkurs teil und wir mussten alle unsere Projekte auf 8-GB-Flash-Laufwerken speichern, da die Computer im Labor, das wir verwendeten, jede Nacht um Mitternacht gelöscht wurden. das hätte alle unsere Arbeit gelöscht. Wenn Sie aus Gründen der Portabilität / Sicherheit / etc. Auf ein externes Speichergerät kompilieren, kann dies sehr lange dauernZeit (auch mit den oben erwähnten vorkompilierten Headern) für die Kompilierung Ihres Programms, insbesondere wenn es sich um ein ziemlich großes Programm handelt. In diesem Fall würde ich Ihnen raten, Programme auf der Festplatte des von Ihnen verwendeten Computers zu erstellen und zu kompilieren. Wenn Sie aus irgendeinem Grund die Arbeit an Ihren Projekten einstellen möchten / müssen, übertragen Sie sie auf Ihre externe Klicken Sie auf das Symbol „Hardware sicher entfernen und Medien auswerfen“, das als kleines Flash-Laufwerk hinter einem kleinen grünen Kreis mit einem weißen Häkchen angezeigt werden soll, um die Verbindung zu trennen.

Ich hoffe das hilft dir; Lass es mich wissen, wenn es so ist! :) :)

cjor530
quelle