Jakich technik można użyć do przyspieszenia czasu kompilacji C ++?
To pytanie pojawiło się w kilku komentarzach do stylu programowania przepełnienia stosu C ++ i jestem zainteresowany usłyszeniem, jakie są pomysły.
Widziałem podobne pytanie: Dlaczego kompilacja w C ++ trwa tak długo? , ale to nie zapewnia wielu rozwiązań.
Odpowiedzi:
Techniki językowe
Idiom Pimpl
Spójrz na idiom Pimpl tutaj i tutaj , znany również jako nieprzezroczysty wskaźnik lub klasy uchwytów. Nie tylko przyspiesza kompilację, ale także zwiększa bezpieczeństwo wyjątków w połączeniu z funkcją wymiany bez rzucania . Idiom Pimpl pozwala zmniejszyć zależności między nagłówkami i zmniejsza liczbę ponownych kompilacji, które należy wykonać.
Przekazywanie deklaracji
Tam, gdzie to możliwe, używaj deklaracji forward . Jeśli kompilator musi tylko wiedzieć, że
SomeIdentifier
jest to struktura, wskaźnik lub cokolwiek innego, nie dołączaj całej definicji, zmuszając kompilator do wykonania większej pracy, niż jest to konieczne. Może to mieć efekt kaskadowy, powodując, że droga będzie wolniejsza niż powinna.Te I / O strumienie są szczególnie znane spowolnienie budowli. Jeśli potrzebujesz ich w pliku nagłówkowym, spróbuj #include
<iosfwd>
zamiast<iostream>
i #include<iostream>
tylko w pliku implementacyjnym.<iosfwd>
Nagłówka posiada deklaracji tylko do przodu. Niestety inne standardowe nagłówki nie mają odpowiedniego nagłówka deklaracji.Preferuj przekazywanie przez odniesienie zamiast przekazywania w podpisach funkcji. Eliminuje to konieczność # włączenia odpowiednich definicji typów w pliku nagłówkowym, a jedynie deklarowanie typu jest konieczne. Oczywiście preferuj stałe odwołania zamiast nie stałych, aby uniknąć niejasnych błędów, ale jest to kwestia dotycząca innego pytania.
Warunki ochrony
Zastosuj warunki ochrony, aby pliki nagłówkowe nie były dołączane więcej niż raz w jednej jednostce tłumaczeniowej.
Używając zarówno pragmy, jak i ifndef, uzyskujesz przenośność prostego rozwiązania makr, a także optymalizację prędkości kompilacji, którą niektóre kompilatory mogą zrobić w obecności
pragma once
dyrektywy.Zmniejsz współzależność
Im bardziej modułowy i mniej współzależny jest twój projekt kodu, tym rzadziej będziesz musiał wszystko kompilować. Możesz także w końcu zmniejszyć ilość pracy, jaką kompilator musi wykonać na dowolnym pojedynczym bloku w tym samym czasie, ponieważ ma mniej do kontrolowania.
Opcje kompilatora
Wstępnie skompilowane nagłówki
Służą do jednokrotnego skompilowania wspólnej sekcji dołączonych nagłówków dla wielu jednostek tłumaczeniowych. Kompilator kompiluje go raz i zapisuje swój stan wewnętrzny. Ten stan można następnie szybko załadować, aby szybko rozpocząć kompilowanie innego pliku z tym samym zestawem nagłówków.
Uważaj, abyś zawierał tylko rzadko zmieniane elementy we wstępnie skompilowanych nagłówkach, w przeciwnym razie możesz często wykonywać pełne przebudowy częściej niż to konieczne. Jest to dobre miejsce dla nagłówków STL i innych plików dołączanych do biblioteki.
ccache to kolejne narzędzie, które wykorzystuje techniki buforowania w celu przyspieszenia działania.
Użyj równoległości
Wiele kompilatorów / IDE obsługuje jednoczesne wykonywanie wielu rdzeni / procesorów. W GNU Make (zwykle używanym z GCC) użyj
-j [N]
opcji. W programie Visual Studio w preferencjach dostępna jest opcja umożliwiająca jednoczesne tworzenie wielu projektów. Możesz także skorzystać z/MP
opcji paralelizmu na poziomie pliku zamiast paralelizmu na poziomie projektu.Inne narzędzia równoległe:
Użyj niższego poziomu optymalizacji
Im bardziej kompilator próbuje zoptymalizować, tym trudniej musi działać.
Udostępnione biblioteki
Przeniesienie rzadziej modyfikowanego kodu do bibliotek może skrócić czas kompilacji. Korzystając z bibliotek współdzielonych (
.so
lub.dll
), możesz również skrócić czas łączenia.Zdobądź szybszy komputer
Więcej pamięci RAM, szybsze dyski twarde (w tym dyski SSD) i więcej procesorów / rdzeni będzie miało wpływ na szybkość kompilacji.
źródło
Pracuję nad projektem STAPL, który jest silnie szablonowaną biblioteką C ++. Raz na jakiś czas musimy ponownie zapoznać się ze wszystkimi technikami, aby skrócić czas kompilacji. Tutaj streściłem stosowane przez nas techniki. Niektóre z tych technik są już wymienione powyżej:
Znajdowanie najbardziej czasochłonnych sekcji
Chociaż nie ma udowodnionej korelacji między długością symboli a czasem kompilacji, zauważyliśmy, że mniejsze średnie rozmiary symboli mogą poprawić czas kompilacji we wszystkich kompilatorach. Twoim pierwszym celem jest znalezienie największych symboli w kodzie.
Metoda 1 - Sortuj symbole według rozmiaru
Możesz użyć
nm
polecenia, aby wyświetlić symbole na podstawie ich rozmiarów:W tym poleceniu
--radix=d
pozwala zobaczyć rozmiary w liczbach dziesiętnych (domyślnie jest to hex). Teraz, patrząc na największy symbol, zidentyfikuj, czy możesz rozbić odpowiednią klasę i spróbuj przeprojektować ją, łącząc nieszablonowe części w klasie bazowej lub dzieląc klasę na wiele klas.Metoda 2 - Sortuj symbole według długości
Możesz uruchomić normalnie
nm
polecenie i przesłać je do swojego ulubionego skryptu ( AWK , Python itp.), Aby posortować symbole na podstawie ich długości . Opierając się na naszym doświadczeniu, ta metoda identyfikuje największe problemy czyniące kandydatów lepszymi niż metoda 1.Metoda 3 - Użyj Templight
„ Templight to narzędzie oparte na Clang do profilowania czasu i zużycia pamięci przez instancje szablonów oraz do wykonywania interaktywnych sesji debugowania w celu uzyskania introspekcji w procesie tworzenia szablonów”.
Możesz zainstalować Templight, sprawdzając LLVM i Clang ( instrukcje ) i stosując na nim łatkę Templight. Domyślne ustawienia dla LLVM i Clang dotyczą debugowania i asercji, które mogą znacząco wpłynąć na czas kompilacji. Wygląda na to, że Templight potrzebuje obu, więc musisz użyć ustawień domyślnych. Proces instalacji LLVM i Clanga powinien zająć około godziny.
Po zastosowaniu poprawki możesz użyć
templight++
kompilacji kodu znajdującego się w folderze kompilacji określonym podczas instalacji.Upewnij się, że
templight++
jest to w ŚCIEŻCE. Teraz, aby skompilować, dodaj następujące przełączniki do swojegoCXXFLAGS
w Makefile lub do opcji wiersza poleceń:Lub
Po zakończeniu kompilacji będziesz mieć .trace.memory.pbf i .trace.pbf wygenerowane w tym samym folderze. Aby wizualizować te ślady, możesz użyć Narzędzi Templight, które mogą przekonwertować je na inne formaty. Postępuj zgodnie z tymi instrukcjami, aby zainstalować konwerter templight. Zwykle używamy wyjścia callgrind. Możesz również użyć wyjścia GraphViz, jeśli twój projekt jest mały:
Wygenerowany plik callgrind można otworzyć za pomocą kcachegrind, w którym można śledzić tworzenie instancji o największym czasie / pamięci.
Zmniejszenie liczby instancji szablonów
Chociaż nie ma dokładnego rozwiązania w celu zmniejszenia liczby instancji szablonów, istnieje kilka wskazówek, które mogą pomóc:
Refaktoryzuj klasy z więcej niż jednym argumentem szablonu
Na przykład, jeśli masz zajęcia,
i zarówno
T
iU
może mieć 10 różnych opcji, to zwiększyła możliwe dawałaby szablonów tej klasy 100. Jednym ze sposobów rozwiązania tego problemu jest abstrakcyjny wspólna część kodu do innej klasy. Inną metodą jest użycie inwersji dziedziczenia (odwrócenie hierarchii klas), ale należy upewnić się, że cele projektowe nie zostaną naruszone przed użyciem tej techniki.Przekieruj kod bez szablonów na poszczególne jednostki tłumaczeniowe
Korzystając z tej techniki, możesz raz skompilować wspólną sekcję i połączyć ją z innymi JT (jednostkami tłumaczeniowymi) później.
Używaj instancji zewnętrznych szablonów (od C ++ 11)
Jeśli znasz wszystkie możliwe wystąpienia klasy, możesz użyć tej techniki do skompilowania wszystkich przypadków w innej jednostce tłumaczeniowej.
Na przykład w:
Wiemy, że ta klasa może mieć trzy możliwe instancje:
Umieść powyższe w jednostce tłumaczeniowej i użyj słowa kluczowego extern w pliku nagłówkowym, poniżej definicji klasy:
Ta technika pozwala zaoszczędzić czas, jeśli kompilujesz różne testy ze wspólnym zestawem instancji.
Używaj kompilacji jedności
Ideą kompilacji jedności jest włączenie wszystkich plików .cc, których używasz w jednym pliku, i skompilowanie tego pliku tylko raz. Korzystając z tej metody, można uniknąć przywracania wspólnych sekcji różnych plików, a jeśli projekt zawiera wiele wspólnych plików, prawdopodobnie zaoszczędziłby również dostęp do dysku.
Jako przykład, załóżmy, masz trzy pliki
foo1.cc
,foo2.cc
,foo3.cc
a wszystkie one należątuple
z STL . Możesz utworzyćfoo-all.cc
wyglądający następująco:Kompilujesz ten plik tylko raz i potencjalnie redukujesz typowe wystąpienia trzech plików. Ogólnie trudno jest przewidzieć, czy poprawa może być znacząca, czy nie. Ale jednym oczywistym faktem jest to, że straciłbyś równoległość w swoich kompilacjach (nie możesz już kompilować trzech plików jednocześnie).
Ponadto, jeśli którykolwiek z tych plików zajmie dużo pamięci, możesz faktycznie zabraknąć pamięci przed zakończeniem kompilacji. W niektórych kompilatorach, takich jak GCC , może to powodować ICE (wewnętrzny błąd kompilatora) z powodu braku pamięci. Więc nie używaj tej techniki, chyba że znasz wszystkie zalety i wady.
Wstępnie skompilowane nagłówki
Wstępnie skompilowane nagłówki (PCH) mogą zaoszczędzić dużo czasu podczas kompilacji, kompilując pliki nagłówkowe do pośredniej reprezentacji rozpoznawalnej przez kompilator. Aby wygenerować wstępnie skompilowane pliki nagłówkowe, wystarczy skompilować plik nagłówkowy za pomocą zwykłego polecenia kompilacji. Na przykład w GCC:
Spowoduje to wygenerowanie
YOUR_HEADER.hpp.gch file
(.gch
to rozszerzenie plików PCH w GCC) w tym samym folderze. Oznacza to, że jeśli uwzględniszYOUR_HEADER.hpp
do jakiegoś innego pliku, kompilator użyje twojegoYOUR_HEADER.hpp.gch
zamiastYOUR_HEADER.hpp
w tym samym folderze wcześniej.Istnieją dwie problemy z tą techniką:
all-my-headers.hpp
.). Ale to oznacza, że musisz dołączyć nowy plik we wszystkich miejscach. Na szczęście GCC ma rozwiązanie tego problemu. Posługiwać się-include
i podaj nowy plik nagłówka. Za pomocą tej techniki możesz przecinać różne pliki.Na przykład:
Używaj nienazwanych lub anonimowych przestrzeni nazw
Nienazwane przestrzenie nazw (inaczej anonimowe przestrzenie nazw) mogą znacznie zmniejszyć generowane rozmiary binarne. Nienazwane przestrzenie nazw wykorzystują wewnętrzne powiązanie, co oznacza, że symbole generowane w tych przestrzeniach nazw nie będą widoczne dla innych JT (jednostki translacji lub kompilacji). Kompilatory zwykle generują unikalne nazwy dla nienazwanych przestrzeni nazw. Oznacza to, że jeśli masz plik foo.hpp:
I zdarza się, że dołączasz ten plik do dwóch JT (dwa pliki .cc i kompilujesz je osobno). Dwa wystąpienia szablonu foo nie będą takie same. Narusza to zasadę jednej definicji (ODR). Z tego samego powodu w plikach nagłówkowych nie zaleca się używania nienazwanych przestrzeni nazw. Używaj ich w swoich
.cc
plikach, aby uniknąć pojawiania się symboli w plikach binarnych. W niektórych przypadkach zmiana wszystkich wewnętrznych szczegółów.cc
pliku wykazała 10% zmniejszenie generowanych rozmiarów binarnych.Zmiana opcji widoczności
W nowszych kompilatorach możesz wybrać symbole, które będą widoczne lub niewidoczne w dynamicznych obiektach współdzielonych (DSO). Idealnie, zmiana widoczności może poprawić wydajność kompilatora, optymalizować czas łącza (LTO) i generować rozmiary binarne. Jeśli spojrzysz na pliki nagłówkowe STL w GCC, zobaczysz, że jest on powszechnie używany. Aby włączyć opcje widoczności, musisz zmienić kod na funkcję, na klasę, na zmienną i, co ważniejsze, na kompilator.
Za pomocą widoczności możesz ukryć symbole, które uważasz za prywatne, przed wygenerowanymi obiektami współdzielonymi. W GCC możesz kontrolować widoczność symboli, przekazując domyślną lub ukrytą
-visibility
opcję kompilatora. Jest to w pewnym sensie podobne do nienazwanej przestrzeni nazw, ale w bardziej wyszukany i nachalny sposób.Jeśli chcesz określić widoczności dla każdego przypadku, musisz dodać następujące atrybuty do swoich funkcji, zmiennych i klas:
Domyślna widoczność w GCC jest domyślna (publiczna), co oznacza, że jeśli skompilujesz powyższą
-shared
metodę jako bibliotekę współdzieloną ( ),foo2
a klasafoo3
nie będzie widoczna w innych JT (foo1
ifoo4
będzie widoczna). Jeśli się skompilujesz,-visibility=hidden
tylkofoo1
widoczne będą. Nawetfoo4
byłby ukryty.Możesz przeczytać więcej o widoczności na GCC wiki .
źródło
Poleciłbym te artykuły z „Games from Within, Indie Game Design And Programming”:
To prawda, że są dość stare - trzeba będzie ponownie przetestować wszystko z najnowszymi wersjami (lub dostępnymi wersjami), aby uzyskać realistyczne wyniki. Tak czy inaczej, jest to dobre źródło pomysłów.
źródło
Jedna technika, która w przeszłości działała dla mnie całkiem dobrze: nie kompiluj wielu plików źródłowych C ++ niezależnie, ale raczej wygeneruj jeden plik C ++, który zawiera wszystkie pozostałe pliki, taki jak ten:
Oczywiście oznacza to, że musisz ponownie skompilować cały dołączony kod źródłowy w przypadku zmiany któregokolwiek ze źródeł, więc drzewo zależności pogarsza się. Jednak kompilowanie wielu plików źródłowych jako jednej jednostki tłumaczeniowej jest szybsze (przynajmniej w moich eksperymentach z MSVC i GCC) i generuje mniejsze pliki binarne. Podejrzewam również, że kompilator ma większy potencjał optymalizacji (ponieważ może zobaczyć więcej kodu na raz).
Ta technika psuje się w różnych przypadkach; na przykład, kompilator wyskoczy, gdy dwa lub więcej plików źródłowych zadeklaruje funkcję globalną o tej samej nazwie. Nie mogłem jednak znaleźć tej techniki opisanej w żadnej z pozostałych odpowiedzi, dlatego właśnie tutaj ją wspominam.
Co do tego jest warte, Projekt KDE zastosował tę samą technikę od 1999 roku, aby zbudować zoptymalizowane pliki binarne (być może w wersji). Wywołano przejście do skryptu konfiguracji kompilacji
--enable-final
. Ze względów archeologicznych wykopałem publikację, która ogłosiła tę funkcję: http://lists.kde.org/?l=kde-devel&m=92722836009368&w=2źródło
<core-count> + N
listy podrzędne, które są kompilowane równolegle, gdzieN
jest odpowiednia liczba całkowita (w zależności od pamięci systemowej i sposobu, w jaki maszyna jest używana).Jest cała książka na ten temat, zatytułowana Large-Scale C ++ Software Design (napisana przez Johna Lakosa).
Książka zawiera wcześniejsze szablony, więc do treści tej książki dodaj „użycie szablonów może spowolnić kompilator”.
źródło
Po prostu odsyłam do mojej innej odpowiedzi: Jak TY skrócisz czas kompilacji i czas łączenia dla projektów Visual C ++ (natywne C ++)? . Kolejną kwestią, którą chcę dodać, ale która często powoduje problemy, jest użycie prekompilowanych nagłówków. Ale proszę, używaj ich tylko do części, które prawie nigdy się nie zmieniają (takich jak nagłówki narzędzi GUI). W przeciwnym razie będą cię kosztować więcej czasu niż zaoszczędzą w końcu.
Inną opcją jest, aby podczas pracy z GNU make włączyć
-j<N>
opcję:Zwykle mam go,
3
odkąd mam tutaj podwójny rdzeń. Następnie uruchomi równolegle kompilatory dla różnych jednostek tłumaczeniowych, pod warunkiem, że nie będzie między nimi zależności. Łączenia nie można wykonać równolegle, ponieważ istnieje tylko jeden proces łączący łączący ze sobą wszystkie pliki obiektowe.Ale sam linker może być wątkowy i to właśnie robi linker ELF . Jest to zoptymalizowany wątkowy kod C ++, o którym mówi się, że łączy pliki obiektowe ELF o wielkość szybciej niż stary (i faktycznie został zawarty w binutils ).
GNU gold
ld
źródło
Oto niektóre:
make -j2
jest to dobry przykład).-O1
niż-O2
lub-O3
).źródło
-j12
dookoła-j18
były znacznie szybsze niż-j8
, tak jak sugerujesz. Zastanawiam się, ile rdzeni możesz mieć, zanim przepustowość pamięci stanie się czynnikiem ograniczającym ...-j
dwukrotności liczby rzeczywistych rdzeni.Po zastosowaniu wszystkich powyższych sztuczek kodu (deklaracje do przodu, ograniczenie włączania nagłówków do minimum w nagłówkach publicznych, wypychanie większości szczegółów w pliku implementacji za pomocą Pimpl ...) i nic więcej nie można uzyskać pod względem językowym, rozważ swój system kompilacji . Jeśli używasz Linuksa, rozważ użycie distcc (kompilator rozproszony) i ccache (kompilator pamięci podręcznej).
Pierwszy, distcc, wykonuje krok preprocesora lokalnie, a następnie wysyła dane wyjściowe do pierwszego dostępnego kompilatora w sieci. Wymaga tej samej wersji kompilatora i biblioteki we wszystkich skonfigurowanych węzłach w sieci.
Ta ostatnia, ccache, jest pamięcią podręczną kompilatora. Ponownie wykonuje preprocesor, a następnie sprawdza za pomocą wewnętrznej bazy danych (przechowywanej w katalogu lokalnym), czy ten plik preprocesora został już skompilowany z tymi samymi parametrami kompilatora. Jeśli tak, po prostu wyświetla plik binarny i dane wyjściowe z pierwszego uruchomienia kompilatora.
Oba mogą być używane jednocześnie, więc jeśli ccache nie ma lokalnej kopii, może wysłać ją przez sieć do innego węzła za pomocą distcc, lub może po prostu wstrzyknąć rozwiązanie bez dalszego przetwarzania.
źródło
Kiedy wyszłam ze studiów, pierwszy prawdziwy kod C ++, który był warty produkcji, miał te tajemne dyrektywy #ifndef ... #endif między nimi, w których zdefiniowano nagłówki. Zapytałem faceta, który pisał kod o tych nadrzędnych rzeczach w bardzo naiwny sposób i zostałem wprowadzony do świata programowania na dużą skalę.
Wracając do sedna, używanie dyrektyw w celu zapobiegania powielaniu definicji nagłówków było pierwszą rzeczą, której nauczyłem się, jeśli chodzi o skrócenie czasu kompilacji.
źródło
Więcej pamięci RAM.
Ktoś mówił o dyskach RAM w innej odpowiedzi. Zrobiłem to z 80286 i Turbo C ++ (pokazuje wiek), a wyniki były fenomenalne. Podobnie jak utrata danych, gdy maszyna uległa awarii.
źródło
W miarę możliwości używaj deklaracji przesyłania dalej. Jeśli deklaracja klasy używa tylko wskaźnika lub odwołania do typu, możesz po prostu zadeklarować go dalej i dołączyć nagłówek typu do pliku implementacji.
Na przykład:
Mniej obejmuje oznacza znacznie mniej pracy preprocesora, jeśli zrobisz to wystarczająco.
źródło
Możesz użyć Kompilacji Jedności .
W pobliżu
źródło
Posługiwać się
u góry plików nagłówkowych, więc jeśli są one dołączone więcej niż raz w jednostce tłumaczącej, tekst nagłówka zostanie uwzględniony i parsowany tylko raz.
źródło
Dla kompletności: kompilacja może być powolna, ponieważ system kompilacji jest głupi, a także ponieważ kompilator zajmuje dużo czasu.
Przeczytaj Rekursywne czyń uważane za szkodliwe (PDF), aby omówić ten temat w środowiskach uniksowych.
źródło
Zaktualizuj komputer
Następnie masz wszystkie inne typowe sugestie
źródło
Miałem pomysł na użycie napędu RAM . Okazało się, że w moich projektach wcale nie robi to żadnej różnicy. Ale wciąż są dość małe. Spróbuj! Chciałbym usłyszeć, jak bardzo to pomogło.
źródło
Łączenie dynamiczne (.so) może być znacznie szybsze niż łączenie statyczne (.a). Zwłaszcza, gdy masz wolny dysk sieciowy. Dzieje się tak, ponieważ masz cały kod w pliku .a, który należy przetworzyć i zapisać. Ponadto na dysk należy zapisać znacznie większy plik wykonywalny.
źródło
Nie o czasie kompilacji, ale o czasie kompilacji:
Użyj ccache, jeśli musisz odbudować te same pliki, gdy pracujesz nad plikami build
Użyj kompilacji ninja zamiast make. Obecnie kompiluję projekt z ~ 100 plikami źródłowymi i wszystko jest buforowane przez ccache. potrzeba 5 minut, ninja mniej niż 1.
Możesz wygenerować swoje pliki ninja z cmake za pomocą
-GNinja
.źródło
Gdzie spędzasz czas? Czy jesteś związany procesorem? Pamięć związana? Dysk związany? Czy możesz użyć więcej rdzeni? Więcej pamięci RAM? Potrzebujesz RAID? Czy chcesz po prostu poprawić wydajność swojego obecnego systemu?
Czy pod gcc / g ++ spojrzałeś na ccache ? Może to być pomocne, jeśli
make clean; make
dużo robisz .źródło
Szybsze dyski twarde.
Kompilatory zapisują na dysku wiele (i być może ogromne) pliki. Praca z dyskiem SSD zamiast typowego dysku twardego i czasy kompilacji są znacznie krótsze.
źródło
W Linuksie (i być może w niektórych innych * NIXach) możesz naprawdę przyspieszyć kompilację, NIE ZATRZYMUJĄC wyjścia i przechodząc na inną TTY.
Oto eksperyment: printf spowalnia mój program
źródło
Udziały sieciowe drastycznie spowalniają twoją kompilację, ponieważ opóźnienia wyszukiwania są wysokie. W przypadku czegoś takiego jak Boost, zrobiło to dla mnie ogromną różnicę, mimo że nasz dysk sieciowy jest dość szybki. Czas na skompilowanie programu doładowania zabawek skrócił się z około 1 minuty do 1 sekundy, kiedy przestawiłem się z udziału sieciowego na lokalny dysk SSD.
źródło
Jeśli masz procesor wielordzeniowy, zarówno Visual Studio (2005 i nowsze wersje), jak i GCC obsługują kompilacje wieloprocesorowe. Na pewno można to włączyć, jeśli masz sprzęt.
źródło
Chociaż nie jest to „technika”, nie mogłem rozgryźć, w jaki sposób Win32 projektuje z wieloma plikami źródłowymi kompilowanymi szybciej niż mój pusty projekt „Hello World”. Mam więc nadzieję, że to pomogło komuś takiemu, jak ja.
W programie Visual Studio jedną z opcji zwiększania czasu kompilacji jest Łączenie przyrostowe ( / INCREMENTAL ). Jest niezgodny z generowaniem kodu czasu łącza ( / LTCG ), więc pamiętaj o wyłączeniu przyrostowego łączenia podczas kompilacji wersji.
źródło
/INCREMENTAL
w trybie debugowaniaPocząwszy od Visual Studio 2017, możesz mieć pewne dane kompilatora dotyczące tego, co wymaga czasu.
Dodaj te parametry do C / C ++ -> Wiersz polecenia (Opcje dodatkowe) w oknie właściwości projektu:
/Bt+ /d2cgsummary /d1reportTime
Możesz mieć więcej informacji w tym poście .
źródło
Użycie dynamicznego linkowania zamiast statycznego powoduje, że kompilator jest szybszy, co można wyczuć.
Jeśli używasz t Cmake, aktywuj właściwość:
Wersja kompilacji, użycie statycznego linkowania może jeszcze bardziej zoptymalizować.
źródło