Velocità di compilazione Java vs velocità di compilazione Scala


101

Sto programmando in Scala da un po 'e mi piace, ma una cosa che mi dà fastidio è il tempo necessario per compilare i programmi. Sembra una cosa da poco, ma con Java potrei apportare piccole modifiche al mio programma, fare clic sul pulsante di esecuzione in netbeans e BOOM, è in esecuzione e nel tempo la compilazione in scala sembra richiedere molto tempo. Ho sentito che con molti progetti di grandi dimensioni un linguaggio di scripting diventa molto importante a causa del tempo impiegato per la compilazione, un'esigenza che non vedevo sorgere quando stavo usando Java.

Ma vengo da Java che, a quanto ho capito, è più veloce di qualsiasi altro linguaggio compilato, ed è veloce per i motivi per cui sono passato a Scala (è un linguaggio molto semplice).

Quindi volevo chiedere, posso fare in modo che Scala si compili più velocemente e scalac sarà mai veloce come javac.


Sembra che alcuni utenti siano d'accordo con te;) twitter.com/etorreborre/status/21286172202
VonC

Go si compila più velocemente di Java. Molto più veloce, il che significa qualcosa.
Daniel C. Sobral

Ahaha, nel mio caso ci vogliono diversi minuti per una compilazione scalac media con poche centinaia di LOC, fsc è leggermente più veloce.
Jeriho

Risposte:


57

Il compilatore Scala è più sofisticato di Java, fornisce inferenza di tipo, conversione implicita e un sistema di tipi molto più potente. Queste funzionalità non sono gratuite, quindi non mi aspetto che scalac sia mai veloce come javac. Ciò riflette un compromesso tra il programmatore che esegue il lavoro e il compilatore che esegue il lavoro.

Detto questo, i tempi di compilazione sono già notevolmente migliorati passando da Scala 2.7 a Scala 2.8, e mi aspetto che i miglioramenti continuino ora che la polvere si è calmata su 2.8. Questa pagina documenta alcuni degli sforzi e delle idee in corso per migliorare le prestazioni del compilatore Scala.

Martin Odersky fornisce molti più dettagli nella sua risposta.


1
VonC

Sono passato da netbeans a ant + jedit (lo so lo so, ant è per gli uomini delle caverne, ma mi evolverò nel mio tempo libero) in modo da poter usare fsc. Ma mi chiedevo, come si confronta la velocità di compilazione di Clojure con quella di Scala? Sembra che abbia molte delle caratteristiche di Scala ma immagino che la sintassi sia molto più facile da analizzare.
user405163

1
Siamo un po 'fuori tema qui, ma il compilatore di Clojure è incredibilmente veloce (molto più veloce di javac su sorgenti equivalenti). Hai ragione sul fatto che è un linguaggio davvero semplice e non ha alcun tipo di sistema di tipi statici, il che aiuta un po '.
Daniel Spiewak

458

Ci sono due aspetti della (mancanza di) velocità per il compilatore Scala.

  1. Maggiore sovraccarico di avvio

    • Lo stesso Scalac consiste in MOLTE classi che devono essere caricate e compilate con jit

    • Scalac deve cercare nel classpath tutti i pacchetti e i file root. A seconda delle dimensioni del percorso di classe, questo può richiedere da uno a tre secondi in più.

    Nel complesso, aspettati un overhead di avvio di scalac di 4-8 secondi, più lungo se lo esegui la prima volta in modo che le cache del disco non siano riempite.

    La risposta di Scala al sovraccarico di avvio è usare fsc o fare costruzione continua con sbt. IntelliJ deve essere configurato per utilizzare entrambe le opzioni, altrimenti il ​​suo overhead anche per i file piccoli è irragionevolmente grande.

  2. Velocità di compilazione più lenta. Scalac gestisce circa 500 fino a 1000 linee / sec. Javac riesce circa 10 volte quello. Ci sono diverse ragioni per questo.

    • L'inferenza del tipo è costosa, in particolare se implica la ricerca implicita.

    • Scalac deve eseguire il controllo del tipo due volte; una volta secondo le regole di Scala e una seconda volta dopo la cancellazione secondo le regole di Java.

    • Oltre al controllo del tipo, ci sono circa 15 passaggi di trasformazione per passare da Scala a Java, che richiedono tempo.

    • Scala genera tipicamente molte più classi per una data dimensione di file rispetto a Java, in particolare se gli idiomi funzionali sono usati pesantemente. La generazione di bytecode e la scrittura di classi richiedono tempo.

    D'altra parte, un programma Scala a 1000 righe potrebbe corrispondere a un programma Java a 2-3K righe, quindi una parte della velocità inferiore se contata in righe al secondo deve essere bilanciata con più funzionalità per riga.

    Stiamo lavorando su miglioramenti della velocità (ad esempio generando file di classe in parallelo), ma non ci si può aspettare miracoli su questo fronte. Scalac non sarà mai veloce come javac. Credo che la soluzione risiederà in server di compilazione come fsc in combinazione con una buona analisi delle dipendenze in modo che solo il set minimo di file debba essere ricompilato. Stiamo lavorando anche su questo.


1
Informazioni sul sovraccarico di avvio dovuto al caricamento della classe: la compilazione anticipata in codice nativo utilizzando GCJ o Mono sarebbe d'aiuto?
Lumaca meccanica

15
E se Scala fosse stato riscritto in C ++? : o)
marcus

Ci sarebbe un vantaggio nell'usare l'istruzione invokedynamic bytecode?
Rob Grant,

40

Dovresti essere consapevole che la compilazione di Scala richiede almeno un ordine di grandezza in più rispetto a Java per compilare. Le ragioni di ciò sono le seguenti:

  1. Convenzioni di denominazione (un file XY.scalafile non deve contenere una classe chiamata XYe può contenere più classi di primo livello). Il compilatore potrebbe quindi dover cercare più file di origine per trovare un dato identificatore di classe / tratto / oggetto.
  2. Impliciti: un uso massiccio di impliciti significa che il compilatore deve cercare qualsiasi conversione implicita nell'ambito di un dato metodo e classificarli per trovare quello "giusto". ( cioè il compilatore ha un dominio di ricerca notevolmente aumentato quando individua un metodo. )
  3. Il sistema dei tipi - il sistema dei tipi scala è molto più complicato di Java e quindi richiede più tempo della CPU.
  4. Inferenza di tipo: l'inferenza di tipo è computazionalmente costosa e un lavoro che javacnon deve essere svolto affatto
  5. scalacinclude un simulatore a 8 bit di una stazione da battaglia completamente armata e operativa, visualizzabile utilizzando la combinazione di tasti magici CTRL-ALT-F12 durante la fase di compilazione di GenICode .

3
@obox_lakes, odio il nitpick, ma Java ha bisogno di inferenza di tipo per metodi parametrizzati int a<T>(T a) {}e poi a(pls_infer_my_type). james-iry.blogspot.com/2009/04/…
Elazar Leibovich

13
@Elazar - sì, lo so. Ma è francamente ridicolo, accanto a scala, chiamare questa "inferenza di tipo"!
oxbow_lakes


19

Il modo migliore per fare Scala è con IDEA e SBT. Imposta un progetto SBT elementare (che farà per te, se lo desideri) ed eseguilo in modalità di compilazione automatica (comando ~compile) e quando salverai il tuo progetto, SBT lo ricompilerà.

È inoltre possibile utilizzare il plug-in SBT per IDEA e allegare un'azione SBT a ciascuna delle configurazioni di esecuzione. Il plug-in SBT fornisce anche una console SBT interattiva all'interno di IDEA.

In entrambi i casi (SBT in esecuzione esternamente o plug-in SBT), SBT rimane in esecuzione e quindi tutte le classi utilizzate nella creazione del progetto vengono "riscaldate" e JIT-ed e il sovraccarico di avvio vengono eliminati. Inoltre, SBT compila solo i file sorgente che ne hanno bisogno. È di gran lunga il modo più efficiente per creare programmi Scala.


9

Le ultime revisioni di Scala-IDE (Eclipse) sono molto migliori nella gestione della compilazione incrementale.

Vedere " Qual è il miglior sistema di compilazione Scala? " Per ulteriori informazioni.


L'altra soluzione è integrare fsc - Fast offline compiler per il linguaggio Scala 2 - (come illustrato in questo post del blog ) come builder nel tuo IDE.

testo alternativo

Ma non direttamente in Eclipse, come menziona Daniel Spiewak nei commenti:

Non dovresti usare FSC all'interno di Eclipse direttamente, se non altro perché Eclipse sta già usando FSC sotto la superficie.
FSC è fondamentalmente un sottile strato sopra il compilatore residente che è precisamente il meccanismo utilizzato da Eclipse per compilare i progetti Scala.


Infine, come mi ricorda Jackson Davis nei commenti:

sbt (Simple build Tool) include anche una sorta di compilazione "incrementale" (tramite l' esecuzione con trigger ), anche se non è perfetta , e la compilazione incrementale migliorata è in lavorazione per la prossima versione 0.9 sbt.


2
sbt può anche fare compilazioni incrementali
Jackson Davis

@ Jackson: esecuzione innescata, giusto! L'ho incluso nella mia risposta.
VonC

2
Non dovresti usare FSC all'interno di Eclipse direttamente, se non altro perché Eclipse sta già usando FSC sotto la superficie. FSC è fondamentalmente un sottile strato sopra il compilatore residente che è precisamente il meccanismo utilizzato da Eclipse per compilare i progetti Scala.
Daniel Spiewak

1
FSC sta per Fast Scala Compiler - non Fast Java Compiler
Ben McCann

@ BenMcCann: oops. Destra. Ho corretto la risposta.
VonC

6

Usa fsc : è un compilatore scala veloce che si trova come attività in background e non ha bisogno di essere caricato tutto il tempo. Può riutilizzare l'istanza del compilatore precedente.

Non sono sicuro che il plugin scala Netbeans supporti fsc (la documentazione lo dice), ma non sono riuscito a farlo funzionare. Prova le build notturne del plugin.


1
Il plugin IntelliJ IDEA Scala ha anche un'opzione per utilizzare fsc
Aaron Novstrup

1
@anovstrup: sì, ma a volte si blocca.
Denis Tulskiy

4

Puoi usare il plugin JRebel che è gratuito per Scala. Quindi puoi "sviluppare nel debugger" e JRebel ricaricherà sempre la classe modificata sul posto.

Ho letto qualche dichiarazione da qualche parte dello stesso Martin Odersky in cui dice che le ricerche di impliciti (il compilatore deve assicurarsi che non ci sia più di un singolo implicito per la stessa conversione per escludere ambiguità) possono tenere occupato il compilatore. Quindi potrebbe essere una buona idea gestire gli impliciti con cura.

Se non deve essere Scala al 100%, ma anche qualcosa di simile, potresti provare Kotlin .

- Oliver


2

Sono sicuro che questo sarà sconsigliato, ma un cambiamento estremamente rapido non è sempre favorevole alla qualità o alla produttività.

Prenditi del tempo per pensare con più attenzione ed eseguire meno micro-cicli di sviluppo. Un buon codice Scala è più denso ed essenziale (cioè privo di dettagli e complessità accidentali). Richiede più pensiero e questo richiede tempo (almeno all'inizio). Puoi progredire bene con un minor numero di cicli di codice / test / debug che sono individualmente un po 'più lunghi e continuano a migliorare la tua produttività e la qualità del tuo lavoro.

In breve: cercare un modello di lavoro ottimale più adatto a Scala.


3
Sono d'accordo sul fatto che non sia essenziale avere un ciclo di inversione rapida. Ma non fa male, vero?
Elazar Leibovich

27
Non ho intenzione di votare per difetto, ma dire che dovresti adattare il tuo schema di lavoro ai limiti del tuo strumento (la bassa velocità del compilatore) piuttosto che cercare di migliorare lo strumento non è un buon argomento. Soprattutto la capacità di eseguire cicli di test rapidi è molto preziosa (anche se non sostituisce la necessità di pensare in profondità, il tipo che probabilmente è meglio farlo lontano dalla tastiera, lo integra bene).
Thilo

9
Penso che la maggior parte della mia produttività sia effettivamente persa a pensare troppo prima di correre. Spesso mi trovo a guardare un'equazione per lunghi periodi cercando di individuare quale potenziale insidia mi sta aspettando, il tutto mentre penso: "Eseguilo e basta!" nella parte posteriore della mia testa. E infatti, quando eseguo il programma imparo molto di più di quanto probabilmente avrei fatto con un'altra o due ore di meditazione. La meditazione è buona, ma sento di aver avuto un uso ottimale della compilazione / meditazione incrementale con java.
user405163

2
Questo è anche simile al suggerire che Shakespeare non dovrebbe usare un correttore ortografico, e invece pensa più attentamente a ciò che vuole dire. Il controllo ortografico automatizzato aiuta con una serie di problemi completamente diversa.
Thilo
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.