2013-08-01 2 views
8

Abbiamo una grande base di codice che ha utilizzato con successo boost :: signals per anni. Recentemente abbiamo deciso di potenziare la v1.54 e abbiamo deciso che, poiché boost: i segnali erano deprecati, avremmo dovuto passare a boost :: signals2.Tempi di compilazione con boost :: signal2 molto lento

Il problema che stiamo vedendo è che i tempi di compilazione sono orrendi. Ad esempio, un piccolo file .cpp impiegherà ora più di 20 secondi in cui era necessario 4.

Analogamente, una delle nostre librerie (grande) che impiegava circa 10 minuti per generare ora richiede fino a un'ora. Ho cercato dappertutto la documentazione su come migliorare questo attraverso intestazioni, macro, ecc precompilati, ma non ho ancora trovato nulla che migliori la situazione.

Visualizzazione cl.exe in procmon rivela una grande quantità di IO nelle librerie boost :: signals2 e mpl.

Non abbiamo bisogno della sicurezza del filetto che i segnali2 forniscono a questo punto siamo vicini a staccare la spina dall'aggiornamento e tornare ai segnali. Qualcuno ha qualche suggerimento o esperienza con questo prima di arrenderci?

Usiamo VS2012 con molta RAM/disco/ecc.

+1

Si sta utilizzando le intestazioni precompilate? –

+8

Signals2 utilizza modelli variadici, sono emulati in VS2012 a costi significativi. Risolto in VS2013. Tra Boost che si adatta a questo e VS2013 sul tuo desktop, dai una manciata di mesi. –

+0

@ HansPassant Grazie per l'informazione, non l'avevo considerato. Dato che non è possibile per noi aspettare che VS2013 sia la migliore linea di condotta per tornare alla libreria dei segnali secondo te? Come è ora, il codice è inutilizzabile a causa dei tempi di compilazione lenti. – pennyowe

risposta

6

In un progetto su cui ho lavorato, tutti gli usi dei segnali di boost erano puntinati in modo tale che le dichiarazioni di inoltro fossero sufficienti. Ciò riduce significativamente il tempo di compilazione poiché le definizioni dei segnali2 vengono analizzate solo quando effettivamente necessarie. Invece di fornire un membro pubblico boost::signals2::signal, la classe ha un membro std :: unique_pointer privato e fornisce una funzione connectToX pubblica che restituisce un oggetto std :: unique_pointer.

class Subject { 
public: 
    boost::signals2::signal<void (int)> valueChanged; 
    void setValue(int x) { 
     valueChanged(x); 
    } 
}; 

class A { 
public: 
    A(Subject& subject): conn(subject.sig.connect([&](int x) {this->onChange(x);}) {} 
    ~A() {conn.disconnect();} 
private: 
    void onChange(x) {} 

    boost::signals2::connection conn; 
}; 

diventa poi un colpo di testa con solo avanti dichiarazioni e non include di spinta intestazioni signals2:

// Header file 
class Subject { 
public: 
    std::unique_ptr<boost::signals2::connection> connect(std::function<void (int)> observer); 

private: 
    class Impl; 
    std::unique_ptr<Impl> mImpl; 
}; 

classi non interessate a segnali ora non c'è bisogno di analizzare le intestazioni signals2. Vale la pena notare che nella mia esperienza la maggior parte del tempo non viene speso nell'analisi del compilatore, ma nel linker. ogni unità di compilazione che utilizza i segnali di boost contiene molte funzioni istanziate che generano informazioni di debug e devono essere eliminate dal linker alla fine. E dato che il linker MS è single-threaded e molto lento, è qui che viene speso il tempo a fare IO. Un SSD ha fornito una buona accelerazione qui.

+0

Grazie per questo feedback. Questa è un'ottima idea (anche se è un peccato che un tale ballo sia necessario). Nel nostro caso non abbiamo considerato l'utilizzo di un pimpl principalmente perché l'uso era così diffuso che il cambiamento sarebbe stato sostanziale. Un'altra ruga è che i client dei segnali utilizzano talvolta il paradigma scoped_connection. Attualmente stiamo aggiornando i nostri file di progetto su VS2013, quindi sarò interessato a vedere se i commenti di @Hans Passant sopra sono veri. – pennyowe

+0

Sì, il pimpl rende molto più complesso l'uso dei segnali, soprattutto perché devi restituire unique_ptrs con le connessioni. Sono abbastanza interessato ai risultati per VS2013, anche se al momento non lavoro su una piattaforma Windows. Non mi aspetto troppi miglioramenti perché il linker non è stato migliorato molto, ed è qui che è stato speso il nostro tempo di costruzione (insieme alla scrittura di file pdb con molte istanze di segnali di boost). Puoi usare cl/Bt + o link/time + per ottenere alcune misurazioni del tempo di costruzione. – Jens