Come gestisci tempi di compilazione sempre più lunghi quando lavori con i modelli?

11

Uso Visual Studio 2012 e ho casi in cui abbiamo aggiunto parametri template a una classe "just" per introdurre un "punto di seam" in modo che in unit test possiamo sostituire quelle parti con oggetti mock.

Come si introducono solitamente punti di cucitura in C ++: utilizzando interfacce e / o missaggio basati su alcuni criteri con interfacce implicite utilizzando anche i parametri dei modelli? Una ragione per chiedere questo è anche perché durante la compilazione a volte un singolo file C ++ (che include file di modelli, che potrebbero includere anche altri modelli) genera un file oggetto che viene generato che occupa circa 5-10 secondi su una macchina dello sviluppatore .

Il compilatore VS non è particolarmente veloce nella compilazione di modelli, per quanto comprendo, e a causa del modello di inclusione dei modelli (praticamente includi la definizione del modello in ogni file che la utilizza indirettamente e probabilmente riattivare quel modello ogni volta che modifichi qualcosa che non ha nulla a che fare con quel modello) potresti avere problemi con i tempi di compilazione (quando esegui la compilazione incrementale).

Quali sono i tuoi modi di gestire il tempo di compilazione incrementale (e non solo) quando lavori con i modelli (oltre a un compilatore migliore / più veloce: -)).

    
posta Ghita 28.11.2012 - 18:50
fonte

3 risposte

9

Se i parametri dei modelli possono solo assumere un insieme di valori limitato (e piccolo), puoi spostare la loro definizione in un file sorgente e utilizzare istanza esplicita .

Ad esempio, in aaa.h dichiari solo le funzioni template f e g :

template <int n>
int f();

template <class T>
void g(int a);

Il parametro del parametro n può essere solo 1, 3, 6 e il parametro del modello T può essere solo int , long e void * .

Quindi li definisci in aaa.cpp in questo modo:

template <int n>
int f()
{
    ...
}

template <class T>
void g(int a)
{
    ...
}

template int f<1>();
template int f<3>();
template int f<6>();

template void g<int>(int a);
template void g<long>(int a);
template void g<void *>(int a);

In questo modo il compilatore crea un'istanza del modello per i parametri specificati durante la compilazione di aaa.cpp . Quando si compila il codice client, si presuppone che le definizioni esistano da qualche parte e il linker si prenderà cura di ciò.

#include "aaa.h"

int main()
{
    f<1>();
    f<3>();
    f<6>();

    g<int>(5);
    g<long>(5);
    g<void *>(5);
}

Puoi anche istanziare esplicitamente delle classi di template. Lo svantaggio è che non puoi utilizzare f o g con altri parametri del modello.

#include "aaa.h"

int main()
{
    f<5>();
}

risultati in

undefined reference to 'int f<5>()'

Ho usato questa tecnica in un progetto in cui poche classi complesse dipendevano da un piccolo (< 10) insieme di parametri di template interi e riduceva significativamente il tempo di compilazione (dal momento che il compilatore non doveva analizzare le definizioni complesse dei template durante la compilazione) il codice cliente). Ovviamente potresti ottenere miglioramenti minori, a seconda del codice effettivo.

    
risposta data 12.01.2013 - 10:36
fonte
1

Una volta ho usato una strana soluzione per un problema simile: l'inclusione dell'STL portava a compilare i tempi come diversi secondi per ogni file sorgente, non importa quanto fosse piccolo. Quindi ho incluso tutti i miei file sorgente in un unico file master e il tempo di compilazione per file non è cambiato ... il che significava una maggiore rapidità del fattore 20+ perché avevo solo un singolo file da compilare.

Per mantenere pulito il progetto, ho continuato a mantenere un makefile, ma non l'ho mai usato (a parte verificare che funzioni ancora).

    
risposta data 11.01.2013 - 22:51
fonte
0

Abbiamo utilizzato una grande attività per creare le nostre intestazioni precompilate e i modelli precompilati durante la notte, e costruire contro quelli il giorno seguente.

    
risposta data 11.01.2013 - 22:38
fonte

Leggi altre domande sui tag