Best Practice - Loop Exit Via Iterator Modification

0

Ho avuto un'interessante discussione con il mio capo oggi sull'uscita da un loop prima che venga soddisfatta la condizione del terminale. Aveva un costrutto in alcuni dei suoi codici VB6 che assomigliava a questo:

Dim Termination As Int
Termination = 10

For Iterator1 = 1 To Termination
    If Iterator1 = 5 Then
        Iterator1 = Termination
    End If
Next

Ho messo in dubbio questa implementazione, sostenendo che un Exit For era il modo corretto di uscire da un ciclo prematuramente in base a una condizione, come questa:

For Iterator2 = 1 To 10
    If Iterator2 = 5 Then
        Exit For
    End If
Next

Ho notato che nella pratica questi probabilmente valutano entrambi lo stesso linguaggio macchina JMP opcode. Il mio capo ha affermato che la sua implementazione potrebbe essere più efficiente poiché avrebbe solo un JMP, quello alla fine del ciclo, anziché due, uno alla fine e uno al centro per l'istruzione Exit For .

Preferisco la seconda implementazione per la leggibilità e la semantica. Inoltre, nelle ultime versioni di Visual Studio per .Net se aggiungi linee dopo l'istruzione Exit For sarai avvisato che nel tuo codice ci sono linee irraggiungibili. Tuttavia, non riceverai questo avviso in VB6, che è il punto in cui è iniziato il dibattito.

Quindi qual è la migliore pratica qui? Il primo esempio è migliore in VB6 o è il secondo esempio migliore in tutte le situazioni? Quali sono i vantaggi / svantaggi di ciascun approccio.

Modifica : numero magico rimosso dall'esempio di codice per migliorare la chiarezza delle domande.

    
posta Bob Mc 07.10.2013 - 22:16
fonte

2 risposte

4

Le prestazioni non dovrebbero essere la tua prima priorità. Di maggiore importanza dovrebbero generalmente essere la leggibilità e la manutenibilità del codice. Exit For indica, in codice, esattamente ciò che vuoi fare, semanticamente. È palesemente ovvio al lettore esattamente ciò che sta facendo il codice.

Quando si imposta la variabile loop è molto meno chiaro. Ho bisogno di trascorrere del tempo cercando di capire cosa sta succedendo; è la variabile di loop impostata alla fine, uno avanti, l'inizio, da qualche parte nel mezzo, o cosa? È tempo che non dovrei aver bisogno di spendere.

Oltre a questo, stai anche ripetendo la costante 10 in quel ciclo. Cosa succede se qualcuno va a cambiare la variabile del ciclo per andare invece a 15. Potrebbero non preoccuparsi di guardare attraverso l'intero corpo del loop e aspettarsi solo che funzioni bene fino a 15 invece. Ora hai un bug molto malvagio. Quando vengo a eseguire il debug del codice, non posso sapere se qualcuno ha voluto la variabile del ciclo da spostare in un'altra posizione interna, o se in realtà dovrebbe essere la fine del ciclo.

Un'altra differenza fondamentale è che End For termina l'iterazione corrente del ciclo adesso . L'impostazione della variabile loop significa che l'iterazione corrente termina e quindi il ciclo si arresta. Se c'è più codice nell'iterazione corrente del ciclo, allora è diverso. È lo stesso se il codice si trova alla fine del ciclo.

Per quanto riguarda le differenze di rendimento, non mi aspetto che ci sia una differenza particolarmente significativa. Nel caso in cui ci sia una differenza, sarà quasi certamente molto, molto, molto piccolo, e non abbastanza per importare. Se, da alcune serie di eventi sorprendenti, sei riuscito a determinare che questo percorso di questo ciclo viene eseguito così frequentemente, e in un contesto in cui le prestazioni sono così importanti, questo cambiamento si traduce in una differenza di prestazioni evidente ed essenziale attraverso il tuo approfondimento test delle prestazioni e profilazione, quindi prendere in considerazione l'utilizzo della versione meno leggibile (possibilmente con commenti di supporto).

    
risposta data 07.10.2013 - 23:06
fonte
0

Ogni volta che esci da un ciclo prima di incontrare le condizioni impostate all'inizio del ciclo, stai causando un comportamento inaspettato. Generalmente non è una buona cosa (è lo stesso problema che hanno le persone con l'affermazione GOTO spesso malgata). Se manipoli manualmente i dati per soddisfare le condizioni migliori, è quasi peggio.

Se voglio eseguire il loop fino a quando non lo interrompo manualmente, utilizzerò una versione di "while (true) {}" e quindi esplicitamente uscirò con un'istruzione exit (). Ciò consente al lettore di sapere che le condizioni principali del loop non governano quando il loop si arresta e non le lascia graffiare la testa quando il codice esce a 10, dopo averlo fatto solo 5 volte.

Uscire da un loop tramite un'impostazione di un valore arbitrario per l'iteratore è comunque il tipo di cosa che mi aspetterei di vedere in VB6. Questa è praticamente una metafora per l'intera lingua.

    
risposta data 07.10.2013 - 22:32
fonte

Leggi altre domande sui tag