In che modo un'istruzione switch è migliore di una serie di istruzioni if? [duplicare]

15

Sto lavorando su un piccolo programma che condurrà un Sort Sort. Un numero verrà immesso attraverso la tastiera e memorizzato in una variabile che ho chiamato "num". Ho deciso di utilizzare un'istruzione switch per ottenere il numero immesso.

switch( e.getKeyCode() ) {

    case KeyEvent.VK_0: num = 0; break;
    case KeyEvent.VK_1: num = 1; break;
    case KeyEvent.VK_2: num = 2; break;
    case KeyEvent.VK_3: num = 3; break;
    case KeyEvent.VK_4: num = 4; break;
    case KeyEvent.VK_5: num = 5; break;
    case KeyEvent.VK_6: num = 6; break;
    case KeyEvent.VK_7: num = 7; break;
    case KeyEvent.VK_8: num = 8; break;
    case KeyEvent.VK_9: num = 9; break;
}

Ho capito che un'altra linea di condotta avrebbe potuto essere l'utilizzo di una serie di istruzioni if.

if( e.getKeyCode() == KeyEvent.VK_0 )
    num = 0;
else if( e.getKeyCode() == KeyEvent.VK_1 )
    num = 1;
etc. for every number up until 9.

Mi sono quindi chiesto quale sia la differenza essenziale tra un'istruzione switch e una serie di istruzioni if. So che risparmia spazio e tempo per scrivere, ma non è così tanto. Quindi, la mia domanda è, a parte lo spazio, un'istruzione switch diversa da una serie di statizioni se in qualche modo? È più veloce, meno soggetto a errori, ecc.?

Questa domanda non influisce molto sul mio codice. Mi stavo chiedendo. Inoltre, questa domanda riguarda il linguaggio JAVA, non altri linguaggi di programmazione.

    
posta kullalok 27.06.2012 - 19:10
fonte

4 risposte

22

Hai ragione che funzionalmente sono identici. In pratica, però, perché dovresti digitare (o tagliare e incollare) tutto ciò quando un'istruzione switch è molto più concisa?

La differenza non è una funzionalità , ma di intento . Quando scrivi un'istruzione switch , stai in effetti dicendo al lettore che questa sezione di codice potrebbe diramarsi in più modi in base allo stato di una singola variabile . Questa affermazione è imposta dal compilatore.

Quando scrivi un blocco if , tuttavia, non stai deliberatamente affermando che è coinvolta solo una variabile. Quando scrivi una serie di if s, come suggerisci, è molto più difficile vedere che la ramificazione si basa solo su una singola variabile. Questo è un problema di manutenzione. Gli sviluppatori che devono modificare il tuo codice in futuro potrebbero non rendersi conto che hai inteso che tale decisione sia così focalizzata e inizi ad aggiungere condizioni che non utilizzano tale variabile. Arriverà qualcuno e dirà "Voglio num 10 come se l'ultima sequenza di tasti fosse 5-4-8" e aggiungere un ulteriore else if alla fine del tuo blocco. Alla fine quella sezione diventerà un nodo di Gourdian di if...else if di condizioni che nessuno può capire. Il futuro ti odierà e il karma negativo verrà aggiunto al tuo account.

Utilizza una dichiarazione switch quando possibile. Comunica chiaramente che questa sezione di codice si basa su una singola variabile ed è molto più a prova di futuro.

    
risposta data 27.06.2012 - 19:22
fonte
10

Il potere di switch è duplice:

  1. È più descrittivo
  2. Salva i cicli della CPU

Il tuo post ha già commenti sulla descrittività di switch rispetto a una catena di if s, quindi mi concentrerò sulla parte 2.

Se il numero di etichette switch è N , una catena di if s accetta O(N) per la spedizione, mentre una switch viene sempre inviata in O(1) . Ecco come si fa: il compilatore posiziona gli indirizzi delle etichette degli switch in una matrice, calcola un indice in base ai valori dell'etichetta ed esegue direttamente un salto, senza confrontare l'espressione di commutazione con il valore uno per uno. Nel caso di stringhe utilizzate come etichette di switch, il compilatore produce una tabella hash, che ricerca anche un indirizzo in O(1) .

Quando il numero di switch diventa elevato (superiore a 100), la conversione tra switch e una catena di if s non può più essere considerata una micro-ottimizzazione: il risparmio di tempo può essere molto significativo, specialmente nei loop stretti . Se un profiler ti dice che la tua catena di if s sta prendendo un tempo significativo, riscrivere come switch potrebbe essere una soluzione.

    
risposta data 27.06.2012 - 19:34
fonte
2

Alcune persone ritengono che il commutatore sia letto più facilmente che in caso contrario. Ma sono d'accordo con la convinzione che preoccuparsi delle prestazioni sia nel campo della micro-ottimizzazione.

SO versione SO di questo Q
SO versione Java di questo Q v2
Versione SO C ++ di questo Q
Versione SO C ++ di questa versione Q v2
SO C # ...

    
risposta data 27.06.2012 - 19:24
fonte
2

Un switch può essere più efficiente di una serie di dichiarazioni if / else if . Vedi questo articolo per un esempio in C. La grande differenza è che con le dichiarazioni if , la condizione per ogni caso può essere qualsiasi cosa. Ad esempio, potresti scrivere un codice che è l'equivalente di:

If it's raining, put on a jacket, otherwise if it's a Sunday, call your mother.

Con un switch , però, ogni confronto sarà un test per l'equivalenza e l'unica cosa che cambia è il valore a cui stai confrontando. Come spiega il collegamento, se i valori per i casi sono tutti vicini l'uno all'altro, il compilatore può implementare lo switch utilizzando una tabella di salto. Cioè, il compilatore può usare il valore che stai attivando per calcolare direttamente l'indirizzo del codice per quel caso. Ciò evita la necessità di una sequenza di confronti. Ora, un compilatore davvero intelligente potrebbe notare che stai usando una serie di dichiarazioni if allo stesso modo e fai la stessa cosa; Non so se sia un'ottimizzazione comune o meno.

Tutto ciò detto, non mi preoccuperei troppo del codice generato dal compilatore. Invece, scegli tra if e switch in base a ciò che sembra naturale per te e per gli altri programmatori. Un switch rappresenta una scelta di un caso su un numero di casi in cui ogni caso ha un valore corrispondente. È un demultiplexer. Se scopri che hai una sequenza di dichiarazioni if che hanno tutte la stessa condizione tranne per il valore che stai confrontando, un switch può essere un modo più bello, più breve, più ovvio per esprimerlo.

    
risposta data 27.06.2012 - 19:25
fonte

Leggi altre domande sui tag