Sto progettando un linguaggio di programmazione e uno dei problemi che stavo pensando è stato il motivo per cui i linguaggi di programmazione richiedono molto tempo per essere compilati. Il C++ presupposto richiede molto tempo perché deve analizzare e compilare un'intestazione ogni volta che compila un file. Ma le intestazioni preconfigurate mi hanno richiesto tanto tempo? sospetto che il C++ non sia l'unico linguaggio che ha questo problema.Perché le compilazioni richiedono così tanto tempo?
risposta
compilazione è un processo complesso che richiede alcuni passaggi piuttosto:
- scansione/Lexing
- Parsing
- generazione del codice intermedio
- ottimizzazione del codice Possibilmente Intermedio
- destinazione generazione di codice macchina
- Opzionalmente ottimizzazione del codice dipendente dalla macchina
(Lasciando da parte il collegamento.)
Naturalmente, questo ci vorrà del tempo per i programmi più lunghi.
Prendono tutto il tempo necessario e di solito dipende da quante cose estranee si iniettano nelle unità di compilazione. Mi piacerebbe vederti compilarli a mano più velocemente :-)
La prima volta che compili un file, non dovresti avere intestazioni. Quindi aggiungili quando ne hai bisogno (e verifica quando hai finito se ne hai ancora bisogno).
Altri modi per ridurre tale tempo è quello di mantenere le unità di compilazione piccole (anche fino a una funzione per file, in un caso estremo) e utilizzare uno strumento simile per assicurarsi di costruire solo ciò che è necessario.
Alcuni compilatori (in realtà IDE) eseguono la compilazione incrementale in background in modo che siano (quasi) sempre vicini alla compilazione completa.
Il linguaggio design fa ha un effetto sulle prestazioni del compilatore. I compilatori C++ sono in genere più lenti dei compilatori C#, che ha molto a che fare con il design della lingua. (Ciò dipende anche dall'implementatore del compilatore, Anders Hejlsberg implementato C# ed è uno dei migliori in circolazione.)
La struttura semplicistica del "file di intestazione" di C++ contribuisce alle sue prestazioni più lente, sebbene spesso le intestazioni precompilate possano essere di aiuto. C++ è un linguaggio molto più complesso di C, e i compilatori C sono quindi in genere più veloci.
Sei sicuro che Anders sia stato coinvolto nell'implementazione del compilatore? Pensavo che fosse più coinvolto da un punto di vista di alto livello, e non giù nel codice del compilatore, ma questa è solo una mia speculazione. – Travis
Sarei sorpreso se non fosse coinvolto in almeno parte dell'attuale implementazione, ma non ne sono sicuro. È sicuramente coinvolto nel design della lingua. –
Delphi e Python vengono in mente come compilatori eccezionalmente veloci ... – Arafangion
Un problema specifico di C++ che lo rende orribilmente lento è che, a differenza di quasi qualsiasi altro linguaggio, non è possibile analizzarlo indipendentemente dall'analisi semantica.
intestazioni precompilate sono modo più veloce, come è stato conosciuto almeno dal 1988.
Il motivo usuale per un compilatore C o compilatore C++ di prendere un lungo periodo di tempo è che ha a # include, pre-elaborazione, e poi lex gazillions di token.
Come esercizio, è possibile scoprire quanto tempo è necessario per eseguire cpp su una tipica raccolta di file di intestazione, quindi misurare il tempo necessario per simulare l'output.
gcc -O utilizza una tecnica di ottimizzazione molto efficace ma un po 'lenta sviluppata da Chris Fraser e Jack Davidson. La maggior parte degli altri ottimizzatori può essere lenta perché coinvolge ripetute iterazioni su strutture di dati abbastanza grandi.
Sarebbe corretto dire che provare ad inserire molta intelligenza nell'ottimizzazione è un modo sicuro per creare lunghi tempi di compilazione? Questa è stata la mia comprensione casuale, ma sono riluttante a fare una dichiarazione generale ... – dmckee
Perché le ottimizazioni non possono essere riutilizzate dalla compilazione precedente, quando solo una frazione del codice è cambiata? O se può essere fatto, come? – HopefullyHelpful
compilazione non necessità di prendere tempo: tcc compila ANSI C abbastanza veloce per essere utile come interprete .
Qualche cosa a cui pensare:
- Complessità nella scansione e passa parsing. Presumibilmente, è necessario ferire lungamente le previsioni, così come le lingue contestuali (al contrario del contesto).
- Rappresentazione interna. Costruire e lavorare su un AST ampio e pieno di funzionalità richiederà del tempo. Presumibilmente, dovresti utilizzare la rappresentazione interna più semplice che supporterà le funzionalità che desideri implementare.
- Ottimizzazione. L'ottimizzazione è pignola. È necessario verificare molte condizioni diverse. Probabilmente vuoi fare più pass. Tutto questo richiederà tempo.
penso che le altre risposte qui hanno perso alcune parti importanti della situazione che rallentano C++ compilazione:
-
modello
- Compilation che salva
.obj
/.o
file su disco, li legge indietro, quindi collega li - collegamento in linkers lenti generali e cattivi, in particolare,
- eccessivamente complesso macro di preprocessore
- arbitrariamente complesso sistema modello di Turing-complete
- inclusione nidificati e ripetuta di file di origine, anche con
#pragma once
- frammentazione User-inflitta, il codice dividendosi in troppi file (anche al punto di una funzione per file, in un caso estremo)
- gonfio o bassa -effort strutture dati interne del compilatore
- Overbloated libreria standard, modello di abuso
al contrario, questi non lento C++ compilazione:
- Scanning/Lexing
- di analisi
- generazione del codice intermedio
- target la generazione di codice macchina
Per inciso, l'ottimizzazione è uno dei più grandi rallentamenti, ma è l'unico rallentamento qui che è effettivamente necessario da una certa misura, ed inoltre è del tutto facoltativo.
- 1. Perché le immagini GIF animate richiedono così tanto tempo per essere caricate?
- 2. Perché l'osservazione dell'oplog richiede così tanto tempo in meteor/mongo?
- 3. Perché ActionDispatch :: Routing :: RouteSet vuole così tanto tempo
- 4. Perché ci vuole così tanto tempo per creare un tavolo?
- 5. Perché Android AVD impiega così tanto tempo per avviarsi?
- 6. vector :: clear() costano così tanto tempo?
- 7. Perché la mia gemma impiega così tanto tempo a caricarsi?
- 8. La creazione di AMI richiede così tanto tempo
- 9. Perché Java G1 gc trascorre così tanto tempo nella scansione di RS?
- 10. Perché ci vuole così tanto tempo prima che Meteor carichi i miei dati su Heroku?
- 11. Perché il primo test eseguito con Robolectric richiede così tanto tempo?
- 12. Perché Visual Studio prende così tanto tempo per aggiungere un progetto o un file
- 13. Perché un sito Meteor distribuito richiede così tanto tempo per essere caricato?
- 14. Perché il pacchetto Macports di GHC impiega così tanto tempo per essere compilato?
- 15. Perché ci vuole così tanto tempo per rinominare una colonna in mysql?
- 16. Perché l'invio di un lavoro a mapreduce richiede così tanto tempo in generale?
- 17. Perché le mie immagini richiedono troppo tempo per essere caricate?
- 18. Perché i breakpoint condizionali rallentano così tanto il mio programma?
- 19. Perché HTML5 si concentra così tanto su Javascript?
- 20. Perché ho impiegato così tanto tempo a scaricare le dipendenze sbt quando creo un progetto scala in un'idea intellij?
- 21. Perché il mio sito ASP.Net in esecuzione su IIS7 impiega così tanto tempo a caricarsi dopo un periodo di inattività?
- 22. Come posso sapere perché il mio codice Perl trascorre così tanto tempo nello spazio del kernel ("sy" in alto)?
- 23. Implementazione di risultati MultiDex nella compilazione per così tanto tempo, e infine errore di heap spazio
- 24. Come mai questi codici Python svolgono così tanto diverso
- 25. La mia applicazione impiega così tanto tempo per avviare la schermata Prima attività
- 26. Perché non c'è GIL nella Java Virtual Machine? Perché Python ne ha bisogno così tanto?
- 27. Perché le classi immutable.js non richiedono "nuovo"?
- 28. Perché le guide richiedono JavaScript Runtime?
- 29. Perché le viste di SQL Server devono essere aggiornate di tanto in tanto
- 30. Perché il conteggio delle righe cambia così tanto da D2007 a D2010?
++ per unità di compilazione più piccole – Thilo