Ich war es gewohnt, in C # im TDD-Stil zu codieren - einen kleinen Codeabschnitt zu schreiben / oder zu ändern, die gesamte Lösung in 10 Sekunden neu zu kompilieren, die Tests erneut auszuführen und noch einmal. Einfach...
Diese Entwicklungsmethode hat für mich einige Jahre lang sehr gut funktioniert, bis ich letztes Jahr wieder auf C ++ zurückgreifen musste und das Gefühl hat, dass meine Produktivität seitdem dramatisch abgenommen hat. Das C ++ als Sprache ist kein Problem - ich hatte ziemlich viel Erfahrung mit C ++ - Entwicklern ... aber in der Vergangenheit.
Meine Produktivität ist für kleine Projekte noch in Ordnung, aber es wird schlimmer, wenn die Projektgröße zunimmt und wenn die Kompilierungszeit mehr als 10 Minuten beträgt, wird es wirklich schlimm. Und wenn ich den Fehler finde, muss ich erneut mit dem Kompilieren beginnen usw. Das ist einfach nur frustrierend.
Daher kam ich zu dem Schluss, dass ein kleiner Teil (wie zuvor) nicht akzeptabel ist - Empfehlungen, wie ich mich in die alte Gewohnheit des Codierens für etwa eine Stunde einarbeiten kann, wenn ich den Code manuell überprüfe (ohne mich auf einen schnellen C # -Compiler zu verlassen). und Komponententests nur einmal in ein paar Stunden neu kompilieren / erneut ausführen.
Mit C # und TDD war es sehr einfach, einen Code evolutionär zu schreiben - nach einem Dutzend Iterationen endete der Mist, mit dem ich angefangen hatte, in einem guten Code, aber er funktioniert für mich nicht mehr (in einer langsamen Kompilierung) Umgebung).
Antworten:
Mir fallen mehrere Dinge ein:
Nutzen Sie die verteilte Zusammenstellung . Sie können dies mit GCC ("distCC"?) Oder VC tun ( Xoreax 'IncrediBuild ist nicht gerade billig, aber jeden Cent wert, der dafür ausgegeben wird.).
Teilen Sie Ihr Projekt in dynamisch geladene Bibliotheken auf und versuchen Sie sorgfältig, die Abhängigkeiten davon zu minimieren. Kleinere ausführbare Dateien verbinden sich viel schneller.
Programmieren Sie eher gegen kleine Testprojekte als gegen die gesamte große Anwendung.
Verwenden Sie Template-Meta-Programmierung, um Algorithmen zur Kompilierungszeit auszuführen . Ja, dies verlängert zwar die Kompilierungszeiten, verringert jedoch auch die zum Testen erforderlichen Bearbeitungszeiten: Wenn die Kompilierung einwandfrei ist, ist sie abgeschlossen.
In Hardware investieren . Mehr CPU-Kernel (auf Ihrem Computer oder in anderen) werden sich bei der verteilten Kompilierung wundern, und viel Speicher sowie eine schnelle Festplatte (SSD anstelle von HDD) werden viel dazu beitragen. Wenn Sie über ein 64-Bit-System und übermäßig viel RAM verfügen, kann das Kompilieren auf einer RAM-Festplatte zu einer unglaublichen Geschwindigkeitssteigerung führen.
quelle
Eine andere technische Lösung, die von anderen noch nicht erwähnt wurde, ist der Umstieg auf Solid State Drives anstelle von regulären Festplatten. In einem früheren Projekt, an dem ich gearbeitet habe, haben SSDs die Build-Zeiten von 30 auf 3 Minuten gesenkt.
Natürlich sind sie teuer. Berechnen Sie für Ihren Chef den Preis für verlorene Entwicklerzeit gegen den Preis für die einmalige Investition. Die Investition macht sich wahrscheinlich in wenigen Monaten bezahlt.
quelle
Mehr Planung, Code in größeren Blöcken, Schreiben von Integrationstests anstelle von Komponententests und Ausführen der build + -Testsuite über Nacht.
quelle
Lange Übersetzungszeiten sind manchmal ein Problem, aber die bereits erwähnte Modularisierung kann (meistens) helfen, das zu überwinden.
Weitaus schwerwiegender ist es, in einer Umgebung zu stecken, in der Sie überhaupt nicht kompilieren können und in der jede Codeänderung einer anderen Abteilung auf einem anderen Kontinent zur Anwendung in der Test- / Entwicklungsumgebung übermittelt werden muss. Dieser Prozess kann Tage in Anspruch nehmen.
Ich arbeite jetzt in einer solchen Umgebung und dieses System hat mich bereits über eine Woche Zeit gekostet (und das Projekt hat nur ein Budget von 4 Wochen, bevor das Geld ausgeht), nur um die erste Version unserer Änderungen zu installieren (Und dann haben sie Fehler gemacht, die dazu geführt haben, dass ein Teil der Dateien nicht vom Anwendungsserver abgerufen wurde. Wir haben also noch einige Tage mit Verzögerungen zu kämpfen.) Jede geringfügige Änderung (sagen wir, wir finden etwas in Tests, das behoben werden muss, z. B. eine verpasste Fehlerbedingung) kann zu einer Verzögerung von einem weiteren Tag oder mehr führen.
Unter solchen Umständen versuchen Sie so sicher wie möglich zu stellen, dass überhaupt keine Fehler vorliegen, bevor Sie versuchen, Ihren Code zu kompilieren. Es fühlt sich fast so an, als wäre ich zurück bei der Mainframe-Programmierung, wo wir für alle Kompilierungs- und Testarbeiten 5 Minuten CPU-Zeit pro Monat zur Verfügung hatten.
quelle
Ich kann mich leicht erinnern, wann Builds lange gedauert haben. Einige mildernde Ansätze:
quelle
10+ Minuten für eine Kompilierung? Ernsthaft?
Verwenden Sie eine IDE, die inkrementelle Builds ausführt (z. B. Eclipse)? Wenn nicht, sollte dies wahrscheinlich der Fall sein, wird die Grundkompilierung in Sekunden und nicht in Minuten durchgeführt.
Oder handelt es sich um Integrationssachen, bei denen Sie die gesamte App erstellen müssen, um Ihre Änderung zu testen? In diesem Fall sollten Sie sich kleinere Tests ansehen, um sicherzustellen, dass die wichtigsten Fehler nicht in Ihrem Code enthalten sind, bevor Sie den vollständigen Build ausführen müssen.
quelle
:-x
Ich war vor einem Jahrzehnt nicht dort, als sie ausgedacht wurden. (Ich habe viel von diesem Code geändert, um TMP zu verwenden, um mehr Fehler beim Kompilieren zu finden und weniger im Feld.)Erstens, warum dauert das Kompilieren so lange?
Wenn Ihre Erstellungszeit danach immer noch langsam ist, lösen Sie das Problem: Erstellen Sie viele kleine Testprojekte und bearbeiten Sie jedes einzeln. Stellen Sie sicher, dass Sie über ein automatisiertes nächtliches Build-System verfügen, das einen neuen Checkout durchführt, alles erstellt und alle Komponententests automatisch ausführt.
Wenn Sie immer noch viel Zeit benötigen, um Ihre Änderungen zu testen, sollten Sie sich eingehender mit ihnen befassen. Stellen Sie vor dem Testen sicher, dass Sie in Ihrem Versionskontrollsystem einen Unterschied machen und alle Änderungen sorgfältig prüfen. Kurz gesagt, ähnelt dies weitgehend der Entwicklung eingebetteter Systeme, bei der die Bearbeitungszeit für einen Test lang ist und Sie nur begrenzt in der Lage sind, den Status des Systems zu überprüfen.
Dies führt mich zu einem anderen Gedanken: Instrumentieren Sie Ihren Code, um die Protokollierung zu verwenden. Auf diese Weise können Sie möglicherweise das Problem erkennen, ohne ein Dutzend Mal neu erstellen und ausführen zu müssen.
quelle
Sie benötigen wahrscheinlich einen mehrpoligen Ansatz:
1) Schnellere Build-Systeme. So viele Kerne / RAM / schnelle Festplatte, wie Sie sich leisten können. Bei größeren C ++ - Projekten ist die Festplatte häufig ein Begrenzer. Stellen Sie daher sicher, dass Sie schnelle haben.
2) Mehr Modularisierung des Projekts. Teilen Sie die Inhalte so auf, dass Änderungen nicht zu einer vollständigen Neukompilierung führen können. Schieben Sie ehrlich gesagt so viele grundlegende Dinge wie möglich in separate DLL / SO-Dateien, damit ein Teil des Projekts vollständig vom Rest getrennt werden kann.
3) Inkrementelle Builds / verteilte Builds / Caching entsprechend Ihrer Umgebung. Auf einigen Systemen kann durch distcc (verteiltes Erstellen) und ccache (Zwischenspeichern von teilweise erstellten Inhalten) viel Kompilierzeit gespart werden.
4) Stellen Sie sicher, dass Ihr Build gut parallelisiert werden kann. Insbesondere in einer Makefile-Umgebung ist es nicht schwer, in eine Situation zu geraten, in der Sie die Makefiles versehentlich so eingerichtet haben, dass Sie keine parallele Erstellung durchführen können.
quelle
Umfangreiche Protokollierung und interne Validierung waren für lange Durchlaufzeiten hilfreich. Sobald Ihr Build fertig ist, kann ein einzelner Durchlauf eine große Anzahl möglicher Probleme auf einmal aufdecken.
Bei komplexen Algorithmen oder der Buchhaltung kann es hilfreich sein, eine stark vereinfachte Version parallel zur "echten" Version einzufügen. In jedem Lauf sind nützliche Referenzdaten enthalten.
quelle
Was @sbi und @Michael Kohne gesagt haben.
Nehmen Sie sich Zeit und Energie für den Build-Prozess. Es war einmal ein stattliches, ausgereiftes Produkt, für dessen Herstellung mehr als eine Stunde benötigt wurde. Es wurde viel Zeit und Energie aufgewendet, um die angeblichen Build-Abhängigkeiten zu reparieren und später zu reduzieren, was sie tatsächlich waren. Die Build-Zeit ist auf ~ 30 Minuten gesunken.
Beim Ändern der Build-Tools wurde es mehr gelöscht. Bei einem mehrteiligen Projekt kann 'scons' alle Kompilierungen durchführen, bevor Verknüpfungen erstellt werden. 'make' mit mehreren Makefiles kompiliert ein einzelnes Projekt, bevor dieses Projekt verknüpft wird, und fährt dann fort.
Das brachte uns zu dem Punkt, dass alle einzelnen Kompilierbefehle massiv parallel ausgeführt werden konnten. 'distcc' auf langsamen Rechnern, make / scons -j8 auf Multicore-Rechnern. Das brachte volle Builds auf ein paar Minuten.
Erstellen Sie in einem anderen Licht einen automatisierten nächtlichen Erstellungsprozess. Auf diese Weise kann verhindert werden, dass mehrere Personen mehrere fehlgeschlagene Builds (erneut) ausführen, wenn Probleme in Ihrem Quell-Repository auftreten.
quelle