Domanda

Trovo che se ci sono un sacco di classi il tempo di compilazione è drammaticamente aumentata quando uso un * .he un * file cpp per classe. Uso già intestazioni precompilate e collegamento incrementale, ma ancora il tempo di compilazione è molto lungo (sì io uso spinta;)

Così mi si avvicinò con il seguente trucco:

  • definiti i file * cpp come non compilabile
  • definiti file * .CXX come compilabile
  • aggiunto un file .cxx * per ogni applicazione modulo e #included tutti i file cpp * di questo modulo in esso.

Così, invece di oltre 100 unità di traduzione ho finito con solo 8 unità di traduzione. La fase di compilazione è diventato 4-5 volte più breve.

Gli svantaggi sono che è necessario includere manualmente tutti i file * cpp (ma non è davvero un incubo di manutenzione in quanto se si dimentica di includere qualcosa il linker vi ricorderà), e che alcune comodità VS IDE non si lavora con questo schema, ad esempio Vai a / Sposta in Attuazione etc.

Quindi la domanda è, sta avendo un sacco di unità di traduzione cpp davvero l'unico modo vero? È il mio trucco uno schema noto, o forse mi manca qualcosa? Grazie!

È stato utile?

Soluzione

Il concetto è chiamato unità accumulo

Altri suggerimenti

Uno svantaggio significativo di questo approccio è causato dalla presenza di file uno obj per ogni unità di traduzione.

Se si crea una libreria statica per il riutilizzo in altri progetti si trovano spesso ad affrontare i binari più grandi in questi progetti, se si dispone di diverse unità di traduzione enormi invece di molte piccole imprese, perché il linker include solo i file obj contenenti le funzioni / variabili in realtà si fa riferimento all'interno del progetto utilizzando la libreria.

In caso di grandi unità di traduzione è più probabile che ogni unità si fa riferimento e il file obj corrispondente è incluso. binari più grandi possono essere un problema in alcuni casi. E 'anche possibile che alcuni linkers sono abbastanza intelligenti per includere solo le necessarie funzioni / variabili, non i file obj interi.

Anche se il file obj è incluso e tutte le variabili globali sono inclusi anche allora i loro costruttori / distruttori saranno chiamati quando viene avviato il programma / fermato che sicuramente ci vorrà del tempo.

Ho visto quello che fai nei videogiochi dal momento che aiuta il compilatore di fare ottimizzazioni altrimenti non poteva fare così come risparmiare un sacco di memoria. Ho visto "uber costruzione" e "accumulo di massa" si riferiscono a questa idea. E se aiuta ad accelerare il costruire, perché non ..

impacchettatrici un maggior numero di file di codice sorgente C ++ in un singolo file è un approccio che è stato menzionato un paio di volte di recente, in particolare quando le persone stavano costruendo grandi sistemi e tirando nei file di intestazione complicate (che sarà spinta, allora) .

Come si menziona VS, ho scoperto che il numero di file di inclusione in un progetto e in particolare la dimensione del percorso di inclusione sembra interessare Visual C ++ 'tempi di compilazione s molto più di quanto non faccia g ++' tempi di compilazione s. Questo è specialmente il caso con un sacco di include annidato (ancora una volta, spinta lo fa) che sono necessarie per trovare tutti i file include richiesti dal codice sorgente di un gran numero di ricerche di file. Combinando il codice in un singolo file di origine significa che il compilatore può essere molto più intelligente di trovare detto comprende, in più ci sono, ovviamente, meno di loro per essere trovato come ci si aspetterebbe che i file nella stessa sottoprogetto sarebbero suscettibili di includere una molto simile set di file di intestazione.

Il "sacco di unità di compilazione" approccio allo sviluppo C ++ di solito proviene da un desiderio di separare le classi e ridurre al minimo le dipendenze tra le classi in modo che il compilatore ha solo per ricostruire il set minimo di file nel caso in cui si apportano modifiche. Questo è generalmente un buon approccio, ma spesso non è davvero possibile in un sottoprogetto, semplicemente perché lì i file hanno dipendenze tra di loro in modo da ritroverete con abbastanza grandi ricostruzioni in ogni caso.

Non credo che la riduzione del numero di unità di compilazione è una buona idea. Il vostro stanno cercando di risolvere un problema con il grande tempo di compilazione, e questo approccio sembra aiutare con esso, ma quello che si ottiene in aggiunta:

  1. Aumento del tempo di compilazione durante lo sviluppo. Di solito sviluppatore modificare alcuni file alla volta, e la compilazione sarà probabilmente più veloce per 3-4 file di piccole dimensioni, allora per una molto grande file.
  2. Come lei ha ricordato, più difficile da navigare codice, IMHO questo è estremamente importante.
  3. Si può avere qualche interferenza tra i file cpp incluso in un unico file .cxx:

    a. E 'pratica comune per definire a livello locale in un file cpp (per build di debug) nuova macro per il controllo perdita di memoria. Purtroppo questo non può essere fatto prima di includere le intestazioni di utilizzare nuova collocazione (come alcuni di intestazione STL e BOOST fare)

    b. E 'pratica comune aggiungere che utilizzano le dichiarazioni nei file cpp. Con il vostro approccio questo può portare a problemi con le intestazioni, incluso tardi

    c. Nome conflitti sono più probabili

secondo me, molto più pulito (ma il modo forse più costoso) per accelerare i tempi di compilazione è quello di utilizzare un po 'di sistema di generazione distribuita. Essi sono particolarmente efficaci per la pulizia costruisce.

Non sono sicuro se questo è rilevante nel tuo caso, ma forse è possibile utilizzare dichiarazione invece la definizione di ridurre il numero di #include 's che si deve fare. Inoltre, forse è possibile utilizzare l'idioma Pimpl per lo stesso scopo. Ciò si spera di ridurre il numero di file di origine che hanno bisogno di essere ricompilato ogni volta e il numero di intestazioni che devono essere tirato dentro.

unità di traduzione più grande e meno non approfittare della compilazione parallela. Non so che cosa i compilatori e quali piattaforme si sta utilizzando, ma la compilazione in più unità di traduzione in parallelo potrebbe diminuire in modo significativo il tempo di costruzione ...

A seguito di sharptooths post, mi piacerebbe tendo a esaminare i file eseguibili risultanti in alcuni dettagli. Se sono diversi, io tendo a limitare la tecnica per build di debug e ricorrere alla configurazione del progetto originale per il build di rilascio principale. Quando si controlla l'eseguibile, mi piacerebbe anche guardare il suo utilizzo occupazione di memoria e di risorse all'avvio e durante l'esecuzione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top