Czy długie kompilacje należą już do przeszłości?

38

Istnieją niezliczone historie wojenne o tym, jak długo może potrwać kompilacja. Nawet xkcd wspomniał o tym.

Od dłuższego czasu nie programuję i przede wszystkim jestem narażony na Javę i Pythona (a Python jest językiem interpretowanym, a nie skompilowanym). Zdaję sobie sprawę, że to możliwe, że po prostu nie spotkałem się z projektami, których kompilacja zajmuje dużo czasu, ale nawet w przypadku aplikacji o przyzwoitych rozmiarach jest to dla mnie natychmiastowe (zwykle obsługiwane w tle przez IDE) lub nie zajmuje więcej niż 30 około sekund dla bardzo dużego projektu. Nawet w środowisku biznesowym (gdzie odbywa się komiks) nigdy nie miałem tak dużo czasu na skompilowanie kodu.

Czy po prostu nie byłem narażony na projekty z długim czasem kompilacji? Czy to relikt przeszłości, który nie jest już czymś, co dzieje się we współczesnym świecie? Dlaczego kompilacja zajmuje tak dużo czasu?

Thunderforge
źródło
31
Spróbuj skompilować chrom.
UldisK,
2
Chwyć kopię jądra systemu Linux. Wykonaj pełną kompilację. Sam zobacz. Lub Spring ze źródła, jeśli jesteś programistą Java. Na razie to pytanie zawiera kilka odpowiedzi, które odpowiadają na pytanie, jakby to była ankieta (odpowiedzi typu „Zrobiłem 30 minut kompilacji ...”), co wskazuje, że samo pytanie nie jest dobrze dopasowane .
Kompilacja ostatniego dużego projektu zajęła mi 40 minut (40 000 plików kodu źródłowego kompiluje się w Maven). Obejściem tego problemu jest sparaliżowanie kompilacji na wielu rdzeniach procesora.
Niklas Rosencrantz
2
Wybierz źródłową dystrybucję Linuksa (gentoo, LFS, ...), a następnie spędzaj dni na kompilowaniu każdego instalowanego oprogramowania.
Basile Starynkevitch
6
zdefiniuj długo ... Dla jakiegoś świeżo po szkole 1 minuta może wydawać się długa, dla oldtimera, który był w okopach od dziesięcioleci, kilka godzin nie podnosi brwi.
jwenting

Odpowiedzi:

48

Kompilacja może trochę potrwać, szczególnie w przypadku dużych projektów napisanych w językach takich jak C, C ++ lub Scala. Kompilowanie części w tle może skrócić czas kompilacji, ale czasami musisz wykonać nową kompilację. Czynniki, które mogą prowadzić do długich czasów kompilacji, obejmują:

  • Oczywiście duży rozmiar kodu. Duże projekty będą miały setki tysięcy wierszy kodu.

  • #includeDyrektywa preprocesora C , która skutecznie powoduje kompilację tego samego kodu setki razy. Makro system ma podobne problemy, ponieważ działa na poziomie tekstu. Preprocesor naprawdę powiększa rozmiar kodu, który jest faktycznie przekazywany do kompilatora. Przeglądanie pliku po wstępnym przetworzeniu (np. Przez gcc -E) powinno otworzyć oczy.

  • Szablony C ++ są kompletne Turinga, co oznacza, że ​​teoretycznie można wykonywać dowolne obliczenia w czasie kompilacji. Nikt tak naprawdę nie chce tego robić, ale nawet wiele prostych przypadków to całkiem sporo czasu poświęconego na specjalizację szablonów.

  • Scala jest dość młodym językiem, a kompilator jest strasznie niedostatecznie zoptymalizowany. Obecnie kompilator używa bardzo dużej liczby przebiegów kompilacji (C został zaprojektowany tak, aby wymagał tylko dwóch przebiegów kompilacji). Sprawdzanie typów jest jednym z tych przejść i może zająć trochę czasu ze względu na skomplikowany system typów opisany przez język.

Kompilacja nie jest jedyną rzeczą, która wymaga czasu. Po skompilowaniu projektu należy uruchomić zestaw testowy. Czas spędzony na tym może wynosić od kilku sekund do kilku godzin (jeśli testy są źle napisane).

amon
źródło
14
W rzeczywistości system typów Scali jest kompletny według Turinga, więc sprawdzenie typu może zająć nieskończoną ilość czasu i kompilator nie może tego ustalić.
Jörg W Mittag
7
Nie zapomnij o optymalizacji. Wiele optymalizacji, które wykona (np.) Kompilator C / C ++, jest bardzo kosztownych (np. Tak drogich, że JIT w ogóle nie może sobie na nie pozwolić). W najgorszym przypadku większość łańcuchów narzędzi obsługuje teraz optymalizację całego programu, o czym wiadomo, że znacznie skraca czas kompilacji.
Brendan
Zaakceptowałem tę odpowiedź, ponieważ wskazałeś kilka rzeczy, których nie rozważałem, w szczególności kompilację całości w porównaniu z kompilacją w kawałkach oraz fakt, że pakiety testowe mogą być uwzględnione w tym czasie „kompilacji”.
Thunderforge
1
nie tylko pakiety testowe - analiza pokrycia kodu, zautomatyzowane pakowanie, automatyczne wdrażanie w systemie testowym; w zintegrowanym systemie kompilacji jest teraz wiele rzeczy. A jeśli jesteś zawieszony, dopóki nie dotrze do środowiska deweloperów lub qa, z pewnością masz czas na potyczki z krzesłem.
corsiKa
1
Świetna odpowiedź, chciałbym tylko zauważyć, że rozkład możliwych czasów kompilacji może być znacznie większy. Pracowałem nad projektami, w których pełna kompilacja może zająć od dwóch do trzech dni (tak, to było przerażające!) I wyobrażam sobie, że są gorsze przestępcy.
Roy T.
17

To wcale nie jest relikt przeszłości. Jeden z projektów, nad którymi pracuję, wymaga 45 minut na czystą wersję od zera. Oprócz naszego własnego kodu musimy również pobrać i zbudować źródło z kilku dużych bibliotek C i C ++ z zewnętrznych repozytoriów. Kompilowanie i łączenie kodu C i C ++ jest kosztowne obliczeniowo. Jak zauważyłeś, Python jest zwykle implementowany jako język interpretowany, a Java zwykle używa kompilatora JIT (Just in Time), więc twoje projekty pomijają wstępną kompilację i łączą koszty. Cena, którą płacisz, to dłuższy czas uruchamiania i (przynajmniej dla Pythona) wolniejsza prędkość wykonania.

Kiedy czasy kompilacji stają się tak długie, coraz ważniejsze staje się korzystanie z systemów ciągłej integracji, takich jak Jenkins lub TeamCity . Pozwala to indywidualnym programistom (głównie) uniknąć bólu związanego z budowaniem od zera, jednocześnie testując, czy zmiany nie psują kompilacji.

Charles E. Grant
źródło
1
javac nie „ całkowicie pomija kompilację z góry i łączy koszty ”. Pomija wiele kosztów optymalizacji, ale nadal przekształca kod źródłowy w kod bajtowy i wykonuje wiele statycznych kontroli w tym procesie. To robi tyle samo linkowania co kompilator C. Rzeczywista różnica w wydajności polega na tym, że proces kompilacji Javy został zaprojektowany w epoce, w której założono, że możliwe jest jednoczesne załadowanie całego programu i jego zależności do pamięci, zamiast konieczności dzielenia go na małe kawałki i ponownego przetwarzania tych samych plików tysiące razy.
Peter Taylor
10

Duże projekty mogą zająć dużo czasu. W przypadku wystarczająco dużego projektu może to potrwać godzinę lub dłużej. Istnieje kilka bibliotek, które muszę skompilować ze źródła na moim komputerze, co zajmuje bardzo dużo czasu - np. Opencascade. Samo jądro Linuksa również zajmuje sporo czasu, jeśli musisz je zbudować od zera.

Istnieją jednak inne procesy podobne do kompilacji, które mogą trwać znacznie dłużej. Projektowanie obwodów cyfrowych (dla układów ASIC lub FPGA) wymaga miejsca i kroku trasy. Etap miejsca i trasy określa miejsce umieszczenia poszczególnych bramek logicznych, przerzutników, rejestrów, pamięci RAM i innych elementów wraz z trasowaniem okablowania wzajemnego. Oprogramowanie wykorzystuje modele czasowe do określania opóźnień bramki i trasy dla możliwych miejsc docelowych, porównuje je z limitami wynikającymi z ograniczeń czasowych, a następnie dostosowuje lokalizacje miejscowe i ścieżki przewodów, aby spróbować spełnić wymagania dotyczące czasu. Czasami oprogramowanie będzie nawet musiało zmieniać rozmiar bramek i dodawać bufory, aby dotrzymać czasu. Ten krok jest niezwykle intensywny obliczeniowo i może potrwać wiele godzin, a nawet dni. Nie jest też zbyt dobrze zrównoleglony. Był projekt FPGA, nad którym pracowałem około rok temu, który zużywał około połowy Virtex 6 HXT 565 FPGA (~ 300 tys. Z 565 tys. LUT) i zajęło około 7 godzin, aby ukończyć miejsce i trasę. Nie potrafię sobie wyobrazić, ile czasu zajmie uruchomienie miejsca i trasy na projekt procesora Core i7 - prawdopodobnie co najmniej kilka tygodni.

alex.forencich
źródło
4

Inne odpowiedzi wspomniały już, że tak, kod w dużych projektach, w których duże oznaczają 500 tys. Linii i więcej, może zająć dużo czasu, szczególnie przy tworzeniu od zera.

Dodatkową kwestią jest to, że niektóre projekty muszą być budowane dla wielu środowisk docelowych. Gdy maszyny obsługujące te środowiska nie są dostępne, kompilacja musi zostać wykonana przez kompilację krzyżową, szeregowo na posiadanych komputerach. Może to prowadzić do znacznych czasów kompilacji. Dla jednego projektu, nad którym pracowałem, nocna kompilacja zajęłaby 10 godzin. Biada, że ​​to ty go złamałeś!

Dodałbym, że nie uniknąłbyś żadnej takiej wymówki na marnowanie czasu. Profesjonalny człowiek powinien planować swoje zadania tak, że nie ma czegoś pożytecznego do zrobienia w takich okresach.

andy256
źródło
3

Trochę obu. C ++ (i C w mniejszym stopniu) były znane ze swoich powolnych czasów kompilacji, szczególnie na sprzęcie z epoki. Na przełomie tysiącleci pracowałem nad projektem, którego zbudowanie zajęło około 4 godzin z powodu makro-shenaniganów.

W dzisiejszych czasach wszystko jest lepsze, ale z mojego doświadczenia wynika, że ​​30 sekund jest dość mało - szczególnie w formalnych kompilacjach, w których należy sprawdzić kontrolę nad źródłem, uruchomić testy jednostkowe, zbudować instalatory i wszystko wysłać gdzieś do SAN.

Telastyn
źródło
2

To zależy od projektu i środowiska, w którym jest skompilowany. Pracowałem nad projektami w C ++, których kompilacja zajęła kilka minut (skonfigurowanych jako wiele projektów w MSVS), co prawdopodobnie wystarcza na walkę na miecze.

Jeśli pracujesz dla dużej firmy z ogromnym kodem i bazą danych (Proctor i Gamble, Google itp.) Lub dla małej firmy lub startupu skoncentrowanego na jednym lub dwóch podstawowych produktach, które są bardzo złożone (np. Symulacja naukowa i rendering), wtedy oczekiwanie na kompilację dużego projektu jest realistyczną rzeczą, której można się spodziewać nawet na potężnych maszynach. Może to wpłynąć na sposób tworzenia i debugowania kodu (a także na częstotliwość aktualizacji i scalania zmian za pomocą wersji).

Trixie Wolf
źródło