Utilizzare più dispatch dinamico potrebbe ridurre i tempi di compilazione?

3

In rapido il tempo di compilazione è molto lento, la quantità di codice nel tuo progetto aumenta. Quindi stavo cercando dei modi per ridurre quel tempo. Un approccio potrebbe essere l'uso di parole chiave linguistiche come definitive o statiche per cambiare il modo in cui il compilatore gestisce il codice in questo caso utilizzando la spedizione statica e dinamica.

Ma per quanto ho letto è meglio evitare l'overhead di runtime riducendo il dispatch dinamico

Quindi il mio primo dubbio è se fare tutto il possibile in runtime usando più dispatch dinamici riduci i tempi di compilazione al costo del sovraccarico di runtime.

Il mio secondo dubbio è che l'overhead di runtime è così brutto? che potresti sacrificare il tempo di compilazione per ridurre il sovraccarico?

    
posta Yo Mariano 05.06.2017 - 07:47
fonte

1 risposta

1

Non ci sono differenze evidenti nei tempi di compilazione per le funzioni inviate staticamente e le funzioni inviate dinamicamente. Sebbene la distribuzione dinamica abbia un sovraccarico extra in fase di esecuzione, in molti casi questo non è evidente: dovrai misurarlo.

Il problema con build incrementali è questo: quando modifico un file, sto potenzialmente cambiando la compatibilità binaria delle cose dichiarate in un file. Per esempio. quando cambio il tipo di ritorno di un metodo, tutto il codice che usa quel metodo dovrà essere ricompilato. Quindi i nostri file sorgente hanno un grafico delle dipendenze di chi usa chi. Quando cambiamo un file che si trova nella parte superiore di questo grafico di dipendenze, devono essere ricompilati anche tutti i file sottostanti e tutti i file che usano quei file e così via. Questo può essere un'enorme cascata.

Quindi il segreto della compilazione rapida è la consapevolezza di queste dipendenze e la rottura delle dipendenze. Idealmente, il tuo grafico delle dipendenze è molto superficiale.

I programmatori C ++ lo sanno molto bene, ma possono tenere traccia delle dipendenze in modo molto preciso vedendo quali file di intestazione sono inclusi. Quando modifico un file di intestazione, anche tutti i file che usano quell'intestazione devono essere ricompilati. Pertanto, i file di intestazione dovrebbero contenere solo dichiarazioni generali che dovrebbero essere stabili e non tutti i dettagli di implementazione che potrebbero essere modificati.

È qui che entra in gioco il dispatch dinamico: quando dipendo direttamente da qualche implementazione concreta, accetto di dover ricompilare quando quell'implementazione cambia, anche se il cambiamento riguarda solo un dettaglio di implementazione. Ma quando dipendo solo da un'interfaccia astratta, devo solo ricompilare quando l'interfaccia cambia. L'implementazione concreta eredita dall'interfaccia e implementa tutti i metodi richiesti da tale interfaccia. Quindi la spedizione dinamica può essere utilizzata per disaccoppiare un client dalle sue dipendenze:

Il client è accoppiato alla sua dipendenza volatile:

+------+    +------------------+
|Client|--->|VolatileDependency|
+------+    +------------------+

Il client è disaccoppiato dalla dipendenza volatile tramite un'interfaccia stabile:

+------+    +---------------+
|Client|--->|StableInterface|
+------+    +---------------+
                     ^
                     |
            +------------------+
            |VolatileDependency|
            +------------------+

Dissociando le unità di compilazione e mantenendo ogni file piccolo e focalizzato, è possibile ridurre il tempo medio per una compilazione incrementale. Tuttavia, l'aggiunta di ulteriori astrazioni rende il progetto nel suo complesso più complicato. Per Swift, questo richiede anche maggiore vigilanza da parte del programmatore per non utilizzare accidentalmente le dipendenze volatili, poiché non sembra esserci un meccanismo di importazione esplicito per classe per dichiarare le dipendenze.

    
risposta data 05.06.2017 - 11:54
fonte

Leggi altre domande sui tag