2009-12-11 6 views
14

Si consideri il seguente esempio di codice:Perché FI ReSharper invertire per codice C#? Fornisce prestazioni migliori (anche leggermente)?

private void AddEnvelope(MailMessage mail) 
{ 
    if (this.CopyEnvelope) 
    { 
     // Perform a few operations 
    } 
} 

vs

private void AddEnvelope(MailMessage mail) 
{ 
    if (!this.CopyEnvelope) return; 
    // Perform a few operations 
} 

Sarà il codice di fondo eseguire qualsiasi più veloce? Perché lo ReSharper dovrebbe fare questa raccomandazione?

Aggiornamento

Dopo aver pensato a questa domanda la risposta potrebbe sembrare ovvio per alcuni. Ma molti di noi sviluppatori non sono mai l'abitudine di nidificazione zounds di if dichiarazioni, in primo luogo ...

+3

Sei stato ingannato se ritieni che questa raccomandazione abbia a che fare con il miglioramento delle prestazioni. In realtà è una clausola di salvaguardia che aiuta a ridurre il numero di percorsi di codice nel metodo. Ciò a sua volta riduce la complessità e semplifica i test e la manutenzione. – Ash

+1

Possibile duplicato: http: // stackoverflow.it/questions/268132/ – CMS

risposta

18

Risposta Aggiornato:

Si tratta di un suggerimento di codice manutenibilità. Più facile da leggere rispetto all'annidamento del resto del codice in un'istruzione IF. Esempi/discussione di questo può essere visto ai seguenti link:

risposta originale:

Verrà effettivamente eseguito (Molto trascurabile) più lento da dover eseguire un'operazione NOT .

Tanto infatti, alcune persone effettivamente considerare che più carina modo per codice in quanto evita un ulteriore livello di rientro per la maggior parte del codice di .

+1

Questa era una raccomandazione per il richiamo. Sono più per le prestazioni che il bel codice per essere onesti ... –

+6

Sì, la differenza qui è se si sta eseguendo un NOT o no. Il vantaggio, tuttavia, è che hai un numero inferiore di nidificazione, che può aumentare la leggibilità a seconda della situazione. –

+13

@ JL: Questa è una micro-ottimizzazione prematura che mi fa impazzire. Il codice leggibile, più facile da leggere (quindi più facile da gestire) dovrebbe sempre essere la priorità, a meno che non si sia verificato un problema di prestazioni. Vedi la risposta di Alex (http://stackoverflow.com/questions/1891259/c-will-inverting-ifs-give-better-performance-even-slightly/1891270#1891270) - è quella corretta. –

45

Non importa. Smettere agonizzante su problemi di prestazioni che non esistono - utilizzano un profiler per identificare le aree nel codice che fanno esporre problemi, e li fissano. L'ottimizzazione proattiva - prima di sapere che c'è un problema - è per definizione una perdita di tempo.

+0

+1 per un buon punto per ricordare JL –

+2

+1. Ad Alex ascolti, JL. Codice per leggibilità e manutenibilità * prima *. Se trovi un punto lento, * quindi * prendi parte a un sacco di trucchi per il codice "intelligente". – Randolpho

+1

Attualmente sto cercando di approfondire la comprensione dei fondamenti del linguaggio. Anche giocando con reSharper, e quando apporta una modifica o una raccomandazione, voglio conoscere la logica dietro al cambiamento. –

0

Questo tipo di "Ottimizzazioni" non vale il tempo speso per il refactoring del codice, perché tutti i compilatori moderni fanno già abbastanza piccole ottimizzazioni da rendere questo tipo di suggerimenti banali. Come accennato in precedenza l'ottimizzazione delle prestazioni avviene attraverso profiler per calcolare quanto il sistema sta eseguendo ed i potenziali colli di bottiglia prima di applicare la correzione delle prestazioni, e poi, dopo la correzione delle prestazioni per vedere se il fix è un bene.

+0

Interessante punto di vista ... dillo ai produttori di ReSharper e ai milioni di sviluppatori là fuori, che si prendono il tempo per ReSharp il loro codice:) –

+0

Vorrei che Resharper arrivasse con un grande adesivo che diceva: "Non importa quanto sia intelligente Resharper, * è ancora più stupido di te. *" Quante persone sembrano fare ciò che dice Resharper "perché Resharper mi ha detto di farlo" senza pensare se sia effettivamente un buon suggerimento. – itowlson

+0

@itowlson, esattamente il motivo della domanda. –

11

È un refactoring di un condizionale che racchiude l'intero contenuto del metodo in un Guard Clause. Non ha nulla a che fare con l'ottimizzazione.

+1

Significa che non ha nulla a che fare con l'ottimizzazione * delle prestazioni *. Sicuramente si tratta di ottimizzare la facilità di manutenzione e leggibilità. – Ash

+0

Infatti. Grazie per il chiarimento. –

3

mi piacciono i commenti sul ottimizzando le cose in questo modo, per aggiungere un po 'di più ad esso ...

L'unica volta che mi viene in mente che ha senso per ottimizzare il vostro istruzioni if ​​è quando si hanno i risultati di DUE o più metodi piuttosto lunga corsa che devono essere combinati per determinare a fare qualcosa di diverso. Si desidera eseguire la seconda operazione solo se la prima operazione ha prodotto risultati che supererebbero la condizione. Mettere quello che è più probabile che restituisca falso prima sarà generalmente una scelta più intelligente. Questo perché se è falso, il secondo non verrà valutato affatto. Ancora una volta, vale la pena preoccuparsi solo se le operazioni sono significative e si può prevedere quale è più probabile che passi o fallisca. Inverti questo per OR ... se è vero, valuterà solo il primo e così ottimizzerà in questo modo. cioè

if (ThisOneUsuallyPasses() && ThisOneUsuallyFails()) 

non è così buono come

if (ThisOneUsuallyFails() && ThisOneUsuallyPasses()) 

perché è solo sul caso strano che il primo funziona in realtà che si deve guardare al secondo. Ci sono altri sapori di questo che puoi derivare, ma penso che dovresti ottenere il punto.

Meglio preoccuparsi di come si usano stringhe, raccolte, indicizzare il database e allocare oggetti piuttosto che passare molto tempo a preoccuparsi della condizione singola se le affermazioni se ci si preoccupa di perf.

In generale, ciò che il codice in basso si dà farà è dare l'opportunità di evitare un enorme blocco di codice all'interno di un'istruzione if che può portare a errori di battitura guidato stupide. Il pensiero della vecchia scuola era che dovresti avere un solo punto di ritorno da un metodo per evitare una diversa generazione di errori del codificatore. Il modo di pensare attuale (almeno da parte di alcuni fornitori di strumenti come il resharper di jetbrains, ecc.) Sembra essere quello che meglio racchiude la minor quantità di codice all'interno delle dichiarazioni condizionali. Qualunque cosa in più sarebbe soggettiva, quindi lascerò perdere. lettura

+0

Sei sicuro che un OR valuterà sempre entrambe le condizioni in C#? Poiché un OR è soddisfatto se una delle due condizioni è TRUE, la valutazione OR dovrebbe cortocircuitare se la prima condizione è VERA, no? Uno XOR deve valutare entrambi i lati, ma quello è un altro animale .... – Val

+0

@Val ack ... modificato. Stavo pensando in termini di negazioni e penso che sia finito nella situazione XOR. Incolpo un caso di "venerdì" ... –

0

richiesto: Cyclomatic_complexity

complessità ciclomatica è una misura quantitativa del numero di percorsi linearmente indipendenti attraverso il codice sorgente di un programma

Il che significa, ogni volta che si ramo utilizzando e if dichiarazione aumenta la complessità ciclomatica di 1.

Per testare ciascuno percorso linearmente indipendente attraverso il programma; in questo caso, il numero di casi di test sarà uguale alla complessità ciclomatica del programma.

Il che significa che se si desidera testare completamente il codice, per ogni istruzione if si dovrà introdurre un nuovo caso di test.

Quindi, con l'introduzione di più se le dichiarazioni della complessità del codice aumenta, come fa il numero di casi di test necessari per testarlo.

Rimuovendo if dichiarazioni, il codice complessità diminuisce così come il numero di casi di test necessari per verificare.

Problemi correlati