2010-03-15 19 views
115

ho incontrato il seguente paragrafo:debug vs prestazioni di uscita

“Debug contro l'impostazione di uscita nell'IDE quando si compila il codice in Visual Studio fa quasi nessuna differenza di prestazioni ... il codice generato è quasi la stessa. Il compilatore C# non esegue alcuna ottimizzazione. Il compilatore C# sputa solo IL ... e al runtime è il JITer che fa tutto l'ottimizzazione. Il JITer ha una modalità Debug/Release e questo fa una grande differenza per le prestazioni. Ma questo non tasto OFF se si esegue il debug o rilascio di configurazione del progetto, che le chiavi fuori se un debugger è collegato.”

La fonte è here e il podcast è here.

Qualcuno può indirizzarmi a un articolo di Microsoft che può effettivamente provarlo?

Googling "C# di debug vs prestazioni rilascio" per lo restituisce i risultati dicendo "Debug ha un sacco di prestazioni colpito", "rilascio è ottimizzato", e "non distribuire il debug alla produzione" .

+0

possibile duplicato di [differenze di prestazioni tra build di debug e release] (http://stackoverflow.com/questions/4043821/performance-differences-tra between-debug-and-release-builds) –

+0

Con .Net4 su Win7-x86 , Ho un programma CPU limitato che ho scritto che gira quasi 2 volte più veloce in versione di debug senza affermazioni/etc nel ciclo principale. – Bengie

+0

Inoltre, se ti interessa l'uso della memoria, ci possono essere grandi differenze. Ho visto un caso in cui un servizio Windows a più thread compilato in modalità Debug utilizzava 700 MB per thread, contro 50 MB per thread nella versione Release. La build di Debug ha esaurito rapidamente la memoria in condizioni di utilizzo tipiche. –

risposta

87

Parzialmente vero. In modalità debug il compilatore emette i simboli di debug per tutte le variabili e compila il codice così com'è. In modalità di rilascio alcune ottimizzazioni sono compresi:

  • variabili non utilizzate non vengono compilati a tutti
  • alcune variabili di loop vengono prese fuori dal giro dal compilatore se sono dimostrati di essere invarianti
  • codice scritto sotto La direttiva #debug non è inclusa, ecc.

Il resto spetta al JIT.

Edit: Lista completa di ottimizzazioni here per gentile concessione di Eric Lippert

+10

E non dimenticarti di Debug.Asserts! In DEBUG build, se falliscono, interromperanno il thread e faranno apparire una finestra di messaggio. Nel rilascio non vengono affatto compilati. Questo vale per tutti i metodi che hanno [ConditionalAttribute]. –

+13

Il compilatore C# non esegue ottimizzazioni delle chiamate tail; il jitter lo fa. Se desideri un elenco accurato di ciò che fa il compilatore C# quando è attiva l'opzione di ottimizzazione, consulta http://blogs.msdn.com/ericlippert/archive/2009/06/11/what-does-the-optimize-switch- do.aspx –

+0

ups. hai ragione Eric. lo rimuoverò dal post –

9

Non posso commentare le prestazioni ma il consiglio "non distribuire il debug in produzione" è ancora valido semplicemente perché il codice di debug di solito fa diverse cose in modo diverso nei prodotti di grandi dimensioni. Per prima cosa, potresti avere le opzioni di debug attive e per un'altra probabilmente ci saranno ulteriori controlli di sicurezza ridondanti e output di debug che non appartengono al codice di produzione.

+0

Sono d'accordo con te su questo problema, ma questo non risponde alla domanda principale – sagie

+5

@sagie: sì, ne sono consapevole, ma ho pensato che valesse ancora la pena farlo. –

2

In msdn sito ...

uscita vs. configurazioni di debug

mentre si sta ancora lavorando sul progetto , in genere verrà creata l'applicazione utilizzando la configurazione di debug , perché questoLa configurazioneconsente di visualizzare il valore di variabili e di controllare l'esecuzione di nel debugger. È inoltre possibile creare e testare build nella configurazione di release per garantire che non abbia introdotto alcun bug che si manifesti solo su un tipo di build o l'altro. In .NET Framework programmazione, tali bug sono molto rari, ma possono verificarsi.

Quando si è pronti per distribuire l'applicazione agli utenti finali, creare una build rilascio, che sarà molto più piccola e di solito hanno molta prestazioni migliori rispetto alla corrispondente configurazione debug. È possibile impostare la configurazione di build nel riquadro Build della finestra di progettazione del progetto o nella barra degli strumenti di costruzione. Per ulteriori informazioni su , consultare Build Configurations.

5

Da msdn social

Non è ben documentato, ecco cosa che so. Il compilatore emette un'istanza di System.Diagnostics.DebuggableAttribute. Nella versione di debug, la proprietà IsJitOptimizerEnabled è Vero, nella versione di rilascio è False. Si può vedere questo attributo nel l'assemblea manifesta con ildasm.exe

Il compilatore JIT utilizza questo attributo per disattivare le ottimizzazioni che fare il debug difficile. Quelle che muovono il codice come sollevamento invariante di loop. Nei casi selezionati , questo può fare una grande differenza in termini di prestazioni. Non di solito però.

La mappatura dei punti di interruzione per l'esecuzione degli indirizzi è il lavoro del debugger. Utilizza il file .pdb e le informazioni generate dal compilatore JIT che fornisce l'istruzione IL per codificare l'indirizzo del codice . Se vuoi scrivere il tuo debugger , devi usare ICorDebugCode :: GetILToNativeMapping().

La distribuzione di debug in genere sarà più lenta poiché le ottimizzazioni del compilatore JIT sono disabilitate.

3

Quello che leggi è abbastanza valido. Il rilascio è solitamente più snello grazie all'ottimizzazione JIT, senza includere il codice di debug (# DEBUG o [Conditional ("DEBUG")]), il minimo del caricamento del simbolo di debug e spesso non viene preso in considerazione è un assembly più piccolo che riduce il tempo di caricamento. Le prestazioni diverse sono più evidenti quando si esegue il codice in VS a causa di PDB e simboli più estesi che vengono caricati, ma se lo si esegue in modo indipendente, le differenze di prestazioni potrebbero essere meno evidenti. Alcuni codici si ottimizzano meglio di altri e utilizza la stessa euristica di ottimizzazione proprio come in altre lingue.

Scott ha una buona spiegazione sull'ottimizzazione metodo in linea here

Vedi this article che danno una breve spiegazione per questo che è diversa in ambiente ASP.NET per l'impostazione debug e rilascio.

+0

La spiegazione in linea è molto buona – sagie

3

Una cosa che dovresti notare, per quanto riguarda le prestazioni e se il debugger è collegato o meno, qualcosa che ci ha colto di sorpresa.

Avevamo un pezzo di codice, che comportava molti loop stretti, che sembravano richiedere sempre un debug, ma funzionava piuttosto bene da solo.In altre parole, nessun cliente o cliente in cui si verificano problemi, ma quando stavamo eseguendo il debug sembrava funzionare come melassa.

Il colpevole era uno Debug.WriteLine in uno dei loop stretti, che sputavano migliaia di messaggi di registro, lasciati da una sessione di debug un po 'di tempo fa. Sembra che quando il debugger è collegato e ascolti tale output, ci sia un sovraccarico che rallenta il programma. Per questo particolare codice, era sull'ordine del runtime 0.2-0.3 secondi e 30+ secondi quando il debugger era collegato.

Soluzione semplice, basta rimuovere i messaggi di debug che non erano più necessari.

0

In gran parte, ciò dipende dal fatto che l'app sia legata all'elaborazione e non è sempre facile dirlo, come nell'esempio di Lasse. Se ho la minima domanda su cosa sta facendo, lo metto in pausa un paio di volte ed esamino lo stack. Se c'è qualcosa in più di cui non ho davvero bisogno, questo lo identifica immediatamente.

54

Non esiste un articolo che "provi" qualcosa su una domanda di prestazioni. Il modo per dimostrare un'affermazione sull'impatto delle prestazioni di un cambiamento è provarlo in entrambi i modi e testarlo in condizioni realistiche ma controllate.

Stai facendo una domanda sulle prestazioni, quindi chiaramente ti preoccupi delle prestazioni. Se ti interessano le prestazioni, la cosa giusta da fare è impostare alcuni obiettivi di rendimento e poi scrivere una suite di test che tenga traccia dei tuoi progressi rispetto a tali obiettivi. Una volta che hai una suite di test, puoi usarla facilmente per testare da te la verità o la falsità di affermazioni come "la build del debug è più lenta".

E inoltre, sarete in grado di ottenere risultati significativi. "Più lento" è privo di significato perché non è chiaro se si tratti di un microsecondo più lento o di venti minuti più lento. "Il 10% più lento in condizioni realistiche" è più significativo.

Passa il tempo che avresti speso a cercare questa domanda online sulla costruzione di un dispositivo che risponda alla domanda. Otterrai risultati molto più precisi in questo modo. Qualunque cosa tu legga online è solo una ipotesi su cosa potrebbe accadere . La ragione dei fatti che hai raccolto tu stesso, non dalle ipotesi di altre persone su come il tuo programma potrebbe comportarsi.

1

Recentemente ho riscontrato un problema di prestazioni. La lista completa dei prodotti richiedeva troppo tempo, circa 80 secondi. Ho sintonizzato il DB, ho migliorato le query e non c'era alcuna differenza. Ho deciso di creare un TestProject e ho scoperto che lo stesso processo è stato eseguito in 4 secondi. Poi ho capito che il progetto era in modalità Debug e il progetto di test era in modalità Release. Ho cambiato il progetto principale in modalità Rilascio e la lista completa dei prodotti ha impiegato solo 4 secondi per visualizzare tutti i risultati.

Riepilogo: la modalità di debug è molto più lenta della modalità di esecuzione in quanto mantiene le informazioni di debug. Devi sempre distribuire in modalità Relase. Puoi comunque avere informazioni di debug se includi file .PDB. In questo modo è possibile registrare gli errori con i numeri di riga, ad esempio.

+0

Per "modalità di esecuzione" intendi "Rilascio"? –

+0

Sì, esattamente. La versione non ha tutto il sovraccarico di debug. –