Questa risposta è specifica per C ++ (come indicato dal tag su questa domanda).
La maggior parte degli altri linguaggi compilati (al di fuori di C e C ++) non hanno questa considerazione, perché in quei linguaggi non c'è alcun vantaggio nello spostare le configurazioni in fase di compilazione. Al di fuori di C e C ++, la compilazione condizionale è strongmente scoraggiata o semplicemente non supportata. Inoltre, i compilatori C e C ++ applicano un'eliminazione aggressiva del codice morto e altre ottimizzazioni in fase di compilazione, in modo che il codice che è dimostrato escludibile dalla configurazione in fase di compilazione non esista nel binario.
Questa domanda può anche diventare un non-problema quando viene presa in considerazione la compilazione just-in-time (JIT). È ampiamente ipotizzato che JIT sarà disponibile per C ++ un giorno.
Da una prospettiva di molti chilometri, ci sono tre considerazioni principali per la configurazione di compilazione vs runtime (o programma di avvio).
Necessità.
La necessità si riferisce a requisiti software, utente o legali che sono rigidi e non possono essere elaborati, e quindi influisce sulla necessità o meno di una configurazione di essere in fase di compilazione o di runtime.
Ad esempio, se è necessario che una configurazione possa essere modificata senza riavviare un'applicazione già in esecuzione, ovviamente tale configurazione deve essere modificabile in fase di esecuzione.
Se il progetto ha una dipendenza opzionale da un componente di terze parti e se quel componente ha termini di licenza che lo rendono inapplicabile a qualche sottoinsieme di clienti, allora dovrai fornire una configurazione di build per includere o escludere il collegamento e utilizzo di quel componente di terze parti dal tuo progetto. Ovviamente quella configurazione deve essere in fase di compilazione.
Burden / Overhead.
Ciò include il costo in termini di tempo e il costo di inconveniente di tutto - la ricompilazione del tempo dell'utente, l'overhead dell'esecuzione del codice (controllo condizionale, configurazioni di lettura, ecc.) e molte altre cose.
Come sottolinea Dan Pichelman nel commento, il tempo speso per la ricompilazione in genere supererà di gran lunga il tempo trascorso su qualsiasi altra cosa.
L'unica eccezione a questa osservazione è che, se per altri motivi, il codice è già stato ricompilato frequentemente, ad esempio, ogni giorno o anche ogni ora. Questo può accadere quando è già presente un sistema di integrazione continua (builds e deployments automatizzati). In tali ambienti, mettere la configurazione in tempo di compilazione può essere efficace perché non ci sono costi aggiuntivi e solo una minore latenza dal cambiamento all'effetto.
gonfiare.
Bloat fa riferimento all'aumento di dimensioni, numero di artefatti di build o altre quantità quando è necessario supportare più configurazioni (sia in fase di compilazione che in fase di esecuzione), rispetto alla stessa quantità quando è necessaria una sola configurazione.
Ad esempio, se si ha la possibilità di utilizzare Algoritmo A contro Algoritmo B per un determinato compito:
- Opzione 1: compila entrambi gli algoritmi nel binario, consentendo così la scelta di essere eseguito in fase di runtime. La dimensione binaria è la somma della dimensione binaria di entrambi gli algoritmi, meno la dimensione delle parti binarie condivise.
- Opzione 2: compila solo uno dei due algoritmi nel binario. La scelta è fissa in fase di compilazione; l'applicazione / utente non sarà in grado di scegliere in fase di runtime.
- Opzione 3: crea una build (binaria) contenente solo Algoritmo A e un'altra build (binaria) contenente solo Algoritmo B. Fornisci entrambi all'utente. Un cambio di scelta richiederà il riavvio dell'applicazione utilizzando il file binario di scelta.
- Opzione 4: refactoring di entrambi gli algoritmi in un modello di algoritmo generalizzato e massimizzazione del riutilizzo della logica, nella speranza di ridurre le dimensioni binarie.
È ovvio che l'Opzione 3 avrà il massimo gonfio, perché molta logica binaria comune a entrambi dovrà essere duplicata. Il rigonfiamento risultante dall'opzione 1 sembra essere ragionevole rispetto all'opzione 3.
L'opzione 2 non ha la scelta runtime, quindi è soggetta ai primi criteri - necessità - a seconda delle esigenze del software e dell'utente.
L'opzione 4 richiede uno sforzo di programmazione extra, ma avrà l'impatto minore sul carico e sull'abbondanza rispetto a tutte le altre opzioni.