Ho un file generato automaticamente, che sembra qualcosa di simile ..."tracking variabile" sta mangiando il mio tempo di compilazione!
static void do_SomeFunc1(void* parameter)
{
// Do stuff.
}
// Continues on for another 4000 functions...
void dispatch(int id, void* parameter)
{
switch(id)
{
case ::SomeClass1::id: return do_SomeFunc1(parameter);
case ::SomeClass2::id: return do_SomeFunc2(parameter);
// This continues for the next 4000 cases...
}
}
Quando costruisco in questo modo, il tempo di costruzione è enorme. Se inline tutte le funzioni automagicamente nei rispettivi casi utilizzando il mio script, il tempo di costruzione è dimezzato. GCC 4.5.0 dice che circa il 50% del tempo di compilazione viene occupato da "monitoraggio variabile" quando uso -ftime-report. Che cosa significa e come posso velocizzare la compilazione mantenendo comunque la localizzazione di cache superiore per estrarre le funzioni dallo switch?
EDIT: Abbastanza interessante, il tempo di costruzione è esploso solo sulla build di debug, secondo le seguenti informazioni profilatura di tutto il progetto (che non è solo il file in questione, ma comunque un buon metrica; il file in questione prende più tempo per costruire):
- Debug: 8 minuti e 50 secondi
- di uscita: 4 minuti, 25 secondi
Se siete curiosi, qui ci sono esempi di alcuni do_func di , co ntext rimosso. Come puoi vedere, ho semplificato la definizione del problema un po 'per mostrare solo le parti rilevanti. Nel caso ve lo stiate chiedendo, tutte le chiamate auto-> func sono chiamate a boost :: signal's.
static void do_Match_Login(Registry* self, const uint8_t* parameters, uint16_t length)
{
const uint8_t* paramPtr = parameters;
std::string p0 = extract_string(parameters, ¶mPtr, length);
std::string p1 = extract_string(parameters, ¶mPtr, length);
int32_t p2 = extract_int32(parameters, ¶mPtr, length);
uint32_t p3 = extract_uint32(parameters, ¶mPtr, length);
tuple<Buffer, size_t, size_t> p4 = extract_blob(parameters, ¶mPtr, length);
return self->Match_Login(p0, p1, p2, p3, p4);
}
static void do_Match_ResponseLogin(Registry* self, const uint8_t* parameters, uint16_t length)
{
const uint8_t* paramPtr = parameters;
int32_t p0 = extract_int32(parameters, ¶mPtr, length);
std::string p1 = extract_string(parameters, ¶mPtr, length);
array<uint16_t, 3> p2 = extract_vector(parameters, ¶mPtr, length);
std::string p3 = extract_string(parameters, ¶mPtr, length);
uint8_t p4 = extract_uint8(parameters, ¶mPtr, length);
uint8_t p5 = extract_uint8(parameters, ¶mPtr, length);
uint64_t p6 = extract_MUID(parameters, ¶mPtr, length);
bool p7 = extract_bool(parameters, ¶mPtr, length);
tuple<Buffer, size_t, size_t> p8 = extract_blob(parameters, ¶mPtr, length);
return self->Match_ResponseLogin(p0, p1, p2, p3, p4, p5, p6, p7, p8);
}
Sembra un caso per Sostituire condizionale con polimorfismo ... –
Ogni do_SomeFuncN è letteralmente 1
Da quando una funzione breve è una scusa per un design difficile da mantenere? Potrebbe non essere necessario generare automaticamente se non hai bisogno di un interruttore così folle. –