Od jakiegoś czasu programuję w Scali i podoba mi się to, ale denerwuje mnie tylko czas kompilacji programów. Wydaje się, że to drobiazg, ale w Javie mogłem wprowadzić drobne zmiany w moim programie, kliknąć przycisk uruchamiania w netbeanach i BOOM, działa, a kompilacja w scali z czasem wydaje się pochłaniać dużo czasu. Słyszałem, że przy wielu dużych projektach język skryptowy staje się bardzo ważny ze względu na czas potrzebny na kompilację, potrzebę, której nie widziałem, gdy używałem Javy.
Ale pochodzę z Javy, która, jak rozumiem, jest szybsza niż jakikolwiek inny język kompilowany i jest szybka z powodów, dla których przesiadłem się na Scala (jest to bardzo prosty język).
Chciałem więc zapytać, czy mogę sprawić, by Scala kompilowała się szybciej i czy scalac będzie kiedykolwiek tak szybki jak javac.
źródło
Odpowiedzi:
Kompilator Scala jest bardziej wyrafinowany niż Java, zapewniając wnioskowanie o typach, niejawną konwersję i znacznie potężniejszy system typów. Te funkcje nie są dostępne za darmo, więc nie spodziewałbym się, że scalac kiedykolwiek będzie tak szybki jak javac. Odzwierciedla to kompromis między programistą wykonującym pracę a kompilatorem wykonującym pracę.
To powiedziawszy, czasy kompilacji już wyraźnie się poprawiły, przechodząc ze Scali 2.7 do Scala 2.8 i spodziewam się, że ulepszenia będą kontynuowane teraz, gdy pył opadł na 2.8. Ta strona dokumentuje niektóre z bieżących wysiłków i pomysłów mających na celu poprawę wydajności kompilatora Scala.
Martin Odersky podaje znacznie więcej szczegółów w swojej odpowiedzi.
źródło
Istnieją dwa aspekty (braku) szybkości kompilatora Scala.
Większe koszty początkowe
Sam Scalac składa się z WIELU klas, które muszą zostać załadowane i skompilowane w jit
Scalac musi przeszukać ścieżkę klas dla wszystkich pakietów i plików głównych. W zależności od rozmiaru ścieżki klas może to zająć od jednej do trzech dodatkowych sekund.
Ogólnie rzecz biorąc, spodziewaj się obciążenia startowego skalac 4-8 sekund, dłuższego, jeśli uruchomisz go po raz pierwszy, aby pamięci podręczne dysku nie zostały zapełnione.
Odpowiedzią Scali na obciążenie początkowe jest użycie fsc lub ciągłe budowanie z sbt. IntelliJ musi być skonfigurowany do używania którejkolwiek z opcji, w przeciwnym razie jego narzut, nawet w przypadku małych plików, jest nieracjonalnie duży.
Wolniejsza prędkość kompilacji. Scalac zarządza około 500 do 1000 linii / sek. Javac radzi sobie około 10 razy tyle. Dzieje się tak z kilku powodów.
Wnioskowanie o typie jest kosztowne, zwłaszcza jeśli obejmuje wyszukiwanie niejawne.
Scalac musi dwukrotnie sprawdzać typ; raz według reguł Scali i drugi raz po skasowaniu według reguł Javy.
Oprócz sprawdzania typów istnieje około 15 kroków transformacji, aby przejść ze Scali do Javy, które wymagają czasu.
Scala zazwyczaj generuje o wiele więcej klas na dany rozmiar pliku niż Java, w szczególności jeśli często używane są idiomy funkcjonalne. Generowanie kodu bajtowego i pisanie klas wymaga czasu.
Z drugiej strony, 1000-wierszowy program Scala może odpowiadać 2-3-kilometrowemu programowi w języku Java, więc część wolniejszej szybkości liczonej w wierszach na sekundę musi być równoważona większą funkcjonalnością na wiersz.
Pracujemy nad poprawą szybkości (np. Poprzez równoległe generowanie plików klas), ale nie można oczekiwać cudów na tym froncie. Scalac nigdy nie będzie tak szybki jak javac. Uważam, że rozwiązaniem będzie kompilacja serwerów, takich jak fsc, w połączeniu z dobrą analizą zależności, tak aby tylko minimalny zestaw plików musiał zostać ponownie skompilowany. Nad tym też pracujemy.
źródło
Należy pamiętać, że kompilacja Scala trwa co najmniej o rząd wielkości dłużej niż kompilacja Java. Przyczyny tego są następujące:
XY.scala
nie musi zawierać klasy o nazwieXY
i może zawierać wiele klas najwyższego poziomu). Dlatego kompilator może być zmuszony do przeszukania większej liczby plików źródłowych, aby znaleźć dany identyfikator klasy / cechy / obiektu.javac
ogóle nie musi być wykonywanescalac
zawiera 8-bitowy symulator w pełni uzbrojonej i operacyjnej stacji bojowej, który można przeglądać za pomocą kombinacji klawiszy magicznych CTRL-ALT-F12 podczas fazy kompilacji GenICode .źródło
int a<T>(T a) {}
i potema(pls_infer_my_type)
. james-iry.blogspot.com/2009/04/…Najlepszym sposobem na zrobienie Scali jest IDEA i SBT. Skonfiguruj elementarny projekt SBT (który zrobi za Ciebie, jeśli chcesz) i uruchom go w trybie automatycznej kompilacji (polecenie
~compile
), a kiedy zapiszesz projekt, SBT dokona ponownej kompilacji.Możesz również użyć wtyczki SBT dla IDEA i dołączyć akcję SBT do każdej z Konfiguracji Run. Wtyczka SBT zapewnia również interaktywną konsolę SBT w ramach IDEA.
Tak czy inaczej (SBT działające zewnętrznie lub wtyczka SBT), SBT pozostaje uruchomione, a zatem wszystkie klasy używane do budowania projektu są „rozgrzewane” i poddawane JIT, a narzut związany z uruchomieniem zostaje wyeliminowany. Ponadto SBT kompiluje tylko pliki źródłowe, które tego potrzebują. Jest to zdecydowanie najbardziej efektywny sposób tworzenia programów Scala.
źródło
Najnowsze wersje Scala-IDE (Eclipse) znacznie lepiej radzą sobie z zarządzaniem kompilacją przyrostową.
Zobacz „ Jaki jest najlepszy system kompilacji Scala? ”, Aby uzyskać więcej informacji.
Innym rozwiązaniem jest integracja fsc - szybkiego kompilatora offline dla języka Scala 2 - (jak pokazano w tym wpisie na blogu ) jako kreatora w swoim IDE.
Ale nie bezpośrednio w Eclipse, o czym Daniel Spiewak wspomina w komentarzach:
Wreszcie, jak przypomina mi Jackson Davis w komentarzach:
sbt (narzędzie do prostego budowania) zawiera również pewnego rodzaju kompilację „przyrostową” (poprzez wykonanie wyzwalane ), mimo że nie jest doskonała , a ulepszona kompilacja przyrostowa jest w przygotowaniu do nadchodzącej wersji 0.9 sbt.
źródło
Użyj fsc - jest to szybki kompilator scala, który działa w tle i nie wymaga ciągłego ładowania. Może ponownie wykorzystać poprzednią instancję kompilatora.
Nie jestem pewien, czy wtyczka Netbeans scala obsługuje fsc (tak mówi dokumentacja), ale nie mogłem go uruchomić. Wypróbuj nocne kompilacje wtyczki.
źródło
Możesz użyć wtyczki JRebel, która jest bezpłatna dla Scala. Możesz więc w pewnym sensie „programować w debugerze”, a JRebel zawsze przeładuje zmienioną klasę na miejscu.
Przeczytałem gdzieś oświadczenie samego Martina Odersky'ego, w którym mówi on, że wyszukiwanie implicitów (kompilator musi upewnić się, że nie ma więcej niż jednej niejawnej dla tej samej konwersji, aby wykluczyć niejednoznaczności) może zająć kompilator. Dlatego dobrym pomysłem może być ostrożne obchodzenie się z implikacjami.
Jeśli nie musi to być w 100% Scala, ale coś podobnego, możesz spróbować Kotlin .
- Oliver
źródło
Jestem pewien, że zostanie to przegłosowane, ale niezwykle szybki zwrot nie zawsze sprzyja jakości lub produktywności.
Poświęć czas na dokładniejsze przemyślenie i wykonaj mniej mikro-cykli programistycznych. Dobry kod Scala jest gęstszy i bardziej istotny (tj. Wolny od przypadkowych szczegółów i złożoności). Wymaga więcej przemyśleń, a to wymaga czasu (przynajmniej na początku). Możesz osiągnąć dobre postępy dzięki mniejszej liczbie cykli kodowania / testowania / debugowania, które są indywidualnie nieco dłuższe i nadal poprawiają produktywność i jakość pracy.
Krótko mówiąc: szukaj optymalnego wzoru roboczego, lepiej pasującego do Scala.
źródło