Qual è l'approccio migliore per la codifica in un ambiente di compilazione lento

15

Ho usato per codificare in C # in uno stile TDD - scrivere / o modificare una piccola porzione di codice, ricompilare in 10 secondi l'intera soluzione, rieseguire i test e di nuovo. Facile ...

Questa metodologia di sviluppo ha funzionato molto bene per me per alcuni anni, fino a un anno in cui ho dovuto tornare alla codifica C ++ e sento davvero che la mia produttività è drasticamente diminuita da allora. Il C ++ come linguaggio non è un problema - ho avuto abbastanza esperienza di sviluppo C ++ ... ma in passato.

La mia produttività è ancora accettabile per un piccolo progetto, ma peggiora quando con l'aumento delle dimensioni del progetto e una volta che il tempo di compilazione raggiunge i 10+ minuti diventa davvero pessimo. E se trovo l'errore, devo ricominciare la compilazione, ecc. Questo è semplicemente frustrante.

Così ho concluso che in piccoli pezzi (come prima) non è accettabile - qualche raccomandazione come posso entrare nella vecchia abitudine di codificare per un'ora o più, quando rivedo il codice manualmente (senza fare affidamento su un veloce Compilatore C #) e solo ricompilando / rieseguendo i test di unità una volta in un paio d'ore.

Con un C # e TDD è stato molto facile scrivere un codice in modo evolutivo - dopo una dozzina di iterazioni, qualsiasi cagata con cui ho iniziato è finito in un buon codice, ma non funziona più per me (in un ambiente di compilazione lento).

    
posta gnat 22.02.2011 - 14:01
fonte

10 risposte

16

Molte cose mi vengono in mente:

  1. Utilizza compilazione distribuita . Puoi farlo con GCC ("distCC"?) O VC ( Xoreax 'IncrediBuild non è esattamente economico, ma vale ogni centesimo speso su di esso.) .

  2. Dividi il tuo progetto in librerie caricate dinamicamente e cerca con cura di minimizzare le dipendenze su di esse. I file eseguibili più piccoli si collegano molto più velocemente.

  3. Programma contro piccoli progetti di test piuttosto che sull'intera grande applicazione.

  4. Utilizza la programmazione template meta per esegui algoritmi in fase di compilazione . Sì, questo in realtà aumenterà i tempi di compilazione, ma ridurrà anche i tempi di risposta necessari per il test: se lo compila bene, è fatto.

  5. Investa hardware . Più kernel di CPU (nella tua macchina o in altri) faranno miracoli con la compilazione distribuita, e molta memoria oltre a un disco veloce (SSD invece di HDD) aiuterà molto. Se si dispone di un sistema a 64 bit e quantità oscene di RAM, la compilazione su un disco RAM potrebbe fornire un incredibile aumento della velocità.

risposta data 22.02.2011 - 14:12
fonte
10

Un'altra soluzione tecnica non ancora menzionata da altri è il passaggio a Solid State Drives anziché normali dischi rigidi. In un precedente progetto su cui ho lavorato, gli SSD hanno ridotto i tempi di costruzione da 30 minuti a 3.

Certo, sono costosi. Per il tuo capo, calcola il prezzo del tempo di sviluppo perduto rispetto al prezzo dell'investimento una tantum. L'investimento probabilmente si ripaga da solo in pochi mesi.

    
risposta data 22.02.2011 - 14:53
fonte
3

Più pianificazione, codice in blocchi più grandi, scrivere test di integrazione invece di unit test ed eseguire la suite build + test durante la notte.

    
risposta data 22.02.2011 - 14:32
fonte
3

A volte i tempi di compilazione lunghi sono un problema, ma la modularizzazione già menzionata può aiutare a superarlo (soprattutto).

Molto più grave è rimanere bloccati in un ambiente in cui non è possibile compilare del tutto, dove ogni cambio di codice deve essere inviato ad un altro reparto in un altro continente per l'applicazione all'ambiente di test / sviluppo, un processo che può richiedere giorni per essere completato .

Ora sto lavorando in un tale ambiente, e questo sistema mi è già costato più di una settimana (e il progetto ha solo un budget di 4 settimane prima che i soldi finiscano) solo per ottenere la versione iniziale di le nostre modifiche sono state installate (e poi hanno commesso errori che causano la mancata raccolta dei file da parte del server delle applicazioni, quindi stiamo esaminando diversi giorni di ritardo). Ogni piccolo cambiamento ora (diciamo che abbiamo trovato qualcosa in fase di test che deve essere corretto, come una condizione di errore persa) può causare un ritardo di un altro giorno o più.

In tali condizioni, provi a fare il più sicuro possibile che non ci siano errori di sorta prima di provare a ottenere il codice compilato. Sembra quasi di tornare alla programmazione su mainframe, dove abbiamo a disposizione 5 minuti di tempo CPU al mese per tutti i lavori di compilazione e test.

    
risposta data 22.02.2011 - 14:51
fonte
3

Posso facilmente ricordare quando le build hanno richiesto molto tempo. Alcuni approcci attenuanti:

  • Costruisci il sistema combinando librerie o DLL. In questo modo, quando modifichi del codice, l'unica parte che deve essere ricompilata è la tua parte.
  • Il numero di punti nel codice che devi modificare per implementare una funzione non solo influenza la quantità di modifiche che devi fare, ma la frequenza con cui inserisci i bug, amplificando il ciclo di compilazione-debug-modifica-compilazione. Tutto ciò che riduce la ridondanza del codice, come DRY, aiuta.
  • Se sei nel debugger e puoi modificare, ricompilare e continuare senza lasciare il debugger, questo è davvero utile.
risposta data 22.02.2011 - 15:06
fonte
2

10+ minuti per una compilazione? Sul serio?

Stai utilizzando un IDE che crea edifici incrementali (ad esempio Eclipse)? Se no, probabilmente dovresti esserlo, eseguirà la compilazione di base in pochi secondi anziché in minuti.

O stai parlando di un'integrazione, in cui devi costruire l'intera app per testare il tuo cambiamento? Se è così, guarda test più piccoli per assicurarti che i principali bug siano fuori dal tuo codice prima di dover fare la compilazione completa.

    
risposta data 22.02.2011 - 14:11
fonte
2

In primo luogo, perché ci vuole così tanto tempo per compilare in primo luogo?

  • Il tuo ambiente (IDE, make, qualunque) supporta build incrementali? Assicurati di aver solo ricompilato le modifiche, piuttosto che il tutto.
  • Se si dispone di un computer multi-core, l'IDE può supportare la compilazione parallela. So per certo che Visual Studio lo fa. Apparentemente anche GCC. Quindi, ottieni una macchina migliore e abilita la compilazione parallela.
  • Considera l'utilizzo di intestazioni precompilate.
  • Se provi tutto questo e la compilazione è ancora lenta, controlla il tuo codice. Cerca dipendenze non necessarie. Stai includendo un'intestazione in cui una dichiarazione anticipata sarebbe sufficiente? Prendi in considerazione l'uso dell'idioma PIMPL per ridurre la dipendenza dalle intestazioni.

Se dopo tutto questo il tempo di costruzione è ancora lento, allora risolvi il problema: crea molti piccoli progetti di test e lavoraci individualmente. Assicurati di avere un sistema di build notturno automatizzato che esegue un nuovo checkout, crea tutto e fa eseguire automaticamente tutti i test unitari.

Infine, se ti ci vuole ancora molto tempo per testare le tue modifiche, allora metti più pensiero su di esse. Assicurati di fare una diff nel tuo sistema di controllo della versione e rivedi attentamente tutte le modifiche prima di testare. In breve, questo è molto simile allo sviluppo di sistemi embedded, in cui i tempi di risposta per un test sono lunghi e la capacità di esaminare lo stato del sistema è limitata.

Questo mi porta ad un altro pensiero: strumenta il tuo codice per usare la registrazione. In questo modo potresti essere in grado di vedere qual è il problema senza ricostruire e rieseguire una dozzina di volte.

    
risposta data 22.02.2011 - 15:07
fonte
1

Probabilmente hai bisogno di un approccio multi-polo:

1) Sistemi di build più veloci. Come molti core / ram / disco veloce come ti puoi permettere. Per progetti C ++ più grandi, troverai che il disco è spesso un limitatore, quindi assicurati di averne uno veloce.

2) Più modularizzazione del progetto. Rompi le cose in modo che le modifiche non possano facilmente causare ricompilazioni complete di tutto. Sinceramente, spingere quante più cose di base possibile in file dll / so separati in modo che parte del progetto possa essere completamente separata dal resto.

3) Build incrementali / build distribuiti / cache in base al tuo ambiente. Su alcuni sistemi, distcc (building distribuito) e ccache (memorizzazione nella cache di materiale parzialmente costruito) può risparmiare molto tempo di compilazione.

4) Assicurati che la tua build possa essere ben parallelizzata. In particolare in un ambiente makefile, non è difficile entrare in una situazione in cui hai accidentalmente configurato i Makefile in modo tale che non puoi creare parallelismi.

    
risposta data 22.02.2011 - 15:31
fonte
0

La registrazione estesa e la convalida interna sono state utili per lunghi tempi di consegna. Una volta terminata la compilazione, una singola esecuzione può rivelare una vasta serie di possibili problemi contemporaneamente.

Quando si affrontano algoritmi o contabilità piuttosto complessi, può essere utile includere una versione molto semplificata in parallelo con quella "reale". In ogni corsa, hai dati di riferimento utili inclusi.

    
risposta data 24.02.2011 - 13:33
fonte
0

Che cosa hanno @sbi e @Michael Kohne.

Dedica tempo ed energia al processo di costruzione stesso. C'era una volta un prodotto imponente e maturo che impiegava più di un'ora per una completa ricostruzione. È stato speso molto tempo ed energie per risolvere ciò che affermavano di essere le dipendenze della build, e in seguito, fissando / riducendo ciò che effettivamente erano. Il tempo di costruzione è sceso a ~ 30 minuti.

La modifica degli strumenti di costruzione lo ha fatto cadere di più. Per un progetto in più parti, 'scons' può fare tutte le compilazioni prima di fare qualsiasi link. 'make' usando più makefile fa una singola compilazione di un progetto prima dei collegamenti di quel progetto, quindi si sposta su.

Questo ci portò al punto che tutti i singoli comandi di compilazione potevano essere eseguiti in modo massivo parallelo. 'distcc' su macchine lente, make / scons -j8 su macchine multicore. Ciò ha portato le build complete a una manciata di minuti.

In una luce diversa, crea un processo di compilazione notturno automatizzato. In questo modo se qualcosa di problematico viene commesso nel tuo repository di origine, la prima persona che arriva al lavoro, vede e risolve il problema, può impedire a più persone di (ri) fare più build falliti.

    
risposta data 04.03.2011 - 00:01
fonte

Leggi altre domande sui tag