17 Stimmen

Wie finde ich heraus, warum g++ für eine bestimmte Datei sehr viel Zeit benötigt?

Ich baue eine Menge von automatisch generierten Code, einschließlich einer besonders großen Datei (~15K Zeilen), mit einem mingw32 Cross-Compiler auf Linux. Die meisten Dateien sind extrem schnell, aber diese eine große Datei nimmt eine unerwartet lange Zeit (~15 Minuten) zu kompilieren.

Ich habe versucht, verschiedene Optimierungsflags zu manipulieren, um zu sehen, ob sie irgendeine Wirkung haben, ohne Erfolg. Was ich wirklich brauche, ist eine Möglichkeit, herauszufinden, was g++ tut, das so lange dauert. Gibt es (relativ einfache) Möglichkeiten, g++ dazu zu bringen, eine Ausgabe über die verschiedenen Phasen der Kompilierung zu erzeugen, um mir dabei zu helfen, die Ursache des Problems einzugrenzen?

Leider bin ich nicht in der Lage, diesen Cross-Compiler neu zu erstellen, so dass es nicht möglich ist, dem Compiler Debugging-Informationen hinzuzufügen und ihn durchzugehen.

Was in der Datei enthalten ist:

  • ein Bündel von Includes
  • eine Reihe von String-Vergleichen
  • eine Reihe von Wenn-dann-Prüfungen und Konstruktoraufrufe

Die Datei ist eine Fabrik für die Erzeugung einer Vielzahl verschiedener spezifischer Unterklassen einer bestimmten übergeordneten Klasse. Die meisten der Includes sind jedoch nicht sonderlich ausgefallen.


Die Ergebnisse von -ftime-report, wie von Neil Butterworth vorgeschlagen, zeigen, dass die Phase "Lebensanalyse" 921 Sekunden dauert, was den größten Teil der 15 Minuten in Anspruch nimmt.

Es scheint, dass dies während der Datenflussanalyse geschieht. Die Datei selbst besteht aus einer Reihe von bedingten String-Vergleichen, bei denen ein Objekt nach dem als String angegebenen Klassennamen konstruiert wird.

Wir denken, dass die Änderung dieses Punktes in eine Abbildung von Namen auf Funktionszeiger die Dinge ein wenig verbessern könnte, also werden wir das versuchen.


Durch die Generierung einer Reihe von Fabrikfunktionen (pro Objekt) und die Erstellung einer Map vom String-Namen des Objekts zu einem Zeiger auf seine Fabrikfunktion konnte die Kompilierzeit von ursprünglich 15 Minuten auf etwa 25 Sekunden reduziert werden, was für jeden eine enorme Zeitersparnis bei der Erstellung von Builds bedeutet.

Nochmals vielen Dank an Neil Butterworth für den Hinweis auf -ftime-report.

0voto

Dave Bacher Punkte 15314

In Verbindung mit @Goz und @Josh_Kelley können Sie gcc/g++ dazu bringen, den vorverarbeiteten Quelltext (mit #includes inline) mit -E auszuspucken. Das ist ein Weg, um festzustellen, wie groß Ihr Quelltext ist.

Und wenn der Compiler selbst das Problem ist, können Sie vielleicht den Kompilierbefehl, der so lange dauert, verfolgen, um herauszufinden, ob es einen bestimmten Dateizugriff oder eine bestimmte interne Aktion gibt, die so lange dauert.

0voto

Clifford Punkte 82130

Was der Compiler sieht, ist die Ausgabe des Präprozessors, so dass die Größe des einzelnen Quelltextes kein gutes Maß ist, man muss den Quelltext und alle darin enthaltenen Dateien sowie die darin enthaltenen Dateien usw. berücksichtigen. Die Instanziierung von Schablonen für mehrere Typen erzeugt Code für jeden einzelnen Typ, der verwendet wird, so dass dies zu einer Menge Code führen kann. Wenn Sie z. B. STL-Container für viele Klassen verwendet haben.

15.000 Zeilen in einem Quelltext sind ziemlich viel, aber selbst wenn man sie aufteilt, muss der gesamte Code immer noch kompiliert werden. Es gibt wirklich keine Notwendigkeit für eine so große Datei; es ist einfach schlechte Praxis/Design. Ich fange an, über eine bessere Modularisierung nachzudenken, wenn eine Datei 500 Zeilen erreicht (obwohl ich da nicht dogmatisch bin).

0voto

Jeremy Friesner Punkte 63019

Während des Kompilierens sollten Sie darauf achten, wie viel Speicherplatz auf Ihrem Computer frei ist. Wenn der Compiler so viel Speicher zuweist, dass der Computer anfängt zu swappen, wird die Kompilierzeit sehr, sehr hoch.

Wenn Sie das beobachten, ist eine einfache Lösung, mehr RAM zu installieren... oder die Datei in mehrere Teile aufzuteilen, die separat kompiliert werden können.

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