Newsgroup: it.comp.lang.c
Titolo: Vantaggi di "Switch" rispetto a "If.. Then"

Ciao a tutti!
Chi gentilmente mi saprebbe dire quali sono i vantaggi, anche pratici 
dell'istruzione "switch" rispetto a "if.. then.. else"?
Ho letto le differenze ma non ho capito il (o i) vantaggio(i)..
Quando conviene uno? Quando l'altro? Limiti di "switch"?
Grazie!
Ciao 


Da quello che so io, non ci sono differenze per il compilatore. I vantaggi 
sono solo una maggiore sinteticità e leggibilità del codice.
Ciao 


Non e' propriamente vero.
La cosa dipende ovviamente molto da compilatore a compilatore.
Se il compilatore riconosce che i vari casi dello switch sono
costanti in un range limitato,
per esempio  10, 11, 13, 14,15,18,
allora invece di fare una serie di if-then-else puo' usare
una tabella di jump e calcolare il jump.
In questo caso per esempio predisporrebbe una tabella con gli
indirizzi a cui saltare per i vari casi e poi potrebbe usare il valore
decrementato di 10 per stabilire a quale indirizzo della tabella saltare.
In casi in cui ci sono moltissimi valori (ma non contigui) potrebbe
riordinare i valori di riferimento e poi fare una ricerca binaria
per ottenere piu' rapidamente il punto a cui saltare, etc.etc.
Dal punto di vista dell'utente medio queste cose possono
non avere influenza particolare sull'efficienza del codice
generato. Quindi direi che la scelta tra switch e una
catena di if dipende piu' da ragioni di chiarezza del codice.
ciao,
g.

 ha scritto nel messaggio 
news:djq8g3$jpv$1...@nnrp.ngi.it...

Oltre i 3 casi vai di "switch" altrimenti "if then" è preferibile, molto 
dipende anche dal processore su cui girerà il codice però..
Per migliorare la velocità puoi partire dai casi più probabili e scendere in 
cascata nei sottocasi con degli "else if".. 

 La cosa dipende ovviamente molto da compilatore a compilatore.
Ciao,
 personalmente mi aspetto che un buon compilatore, con un minimo di
ottimizzazione richiesta da linea di comando, non faccia alcuna differenza
tra uno switch e un if.
Che poi i compilatori non siano tutti buoni, questo ci posso credere :-)
 Ciao
 Federico

 tra uno switch e un if.
perche' non dovrebbe fare differenze? sono due costrutti diversi,
anche statisticamente usati in modi diversi.
Il fatto che poi uno switch si possa convertire in una catena di
if then else + eventualmente dei salti o ripetizione di codice per
simulare il proseguimento di un caso nell'altro, non significa
necessariamente che chi progetta il compilatore preveda le stesse
ottimizzazioni per lo switch e gli if allo stesso livello di ottimizzazione.
Ottimizzare uno switch con una jump table e' una cosa "naturale",
visto che spesso gli switch si usano proprio per discriminare tra 
costanti in un range limitato (tipo: i char), quindi mi aspetterei
di trovarla anche a livelli di ottimizzazione abbastanza bassi.
Viceversa quello di avere una catena lunga di if-then-else, tutti
basati su confronti di uguaglianza e tutti sulla stessa variabile
e' una cosa piu' rara da trovare e piu' dispendiosa da riconoscere,
quindi mi immagino che possa essere una ottimizzazione relegata tra
quelle che si effettuano solo a livelli di ottimizzazione alta.
Per esempio, sulla mia macchina, il gcc della gnu (un compilatore che
direi piu' che accettabile), passandogli un programmino che contiene 
questo :
switch(n)
{
case  1: y = fun(n,55); break;
case      2: y = fun(n,15); break;
case      3: y = fun(n,25); break;
case      4: y = fun(n,35); break;
case      5: y = fun(n,45); break;
case      6: y = fun(n,55); break;
case      7: y = fun(n,65); break;
case      8: y = fun(n,75); break;
case      9: y = fun(n,85); break;
case      10: y = fun(n,95); break;
case      11: y = fun(n,105); break;
}
mi genera appunto una jump table mentre per questo codice
   if (n==1) y = fun(n,55);
   else  if (n==2) y = fun(n,15);
   else  if (n==3) y = fun(n,25);
   else  if (n==4) y = fun(n,35);
   else  if (n==5) y = fun(n,45);
   else  if (n==6) y = fun(n,55);
   else  if (n==7) y = fun(n,65);
   else  if (n==8) y = fun(n,75);
   else  if (n==9) y = fun(n,85);
   else  if (n==10) y = fun(n,95);
   else  if (n==11) y = fun(n,105);
mi genera una catena di test e salti.
ciao,
g.

 mi genera una catena di test e salti.
Ti credi sulla parola, anche perche' non so nulla di assembler e non 
potrei verificare :-)
Ma tu hai chiesto al gcc di ottimizzare?
 Ciao
 Federico

 Ma tu hai chiesto al gcc di ottimizzare?
Anche io so poco (conoscevo bene l'assembler del Motorola 6502...)
pero' l'output prodotto con il "gcc -S" e' abbastanza comprensibile,
almeno si vede bene la struttura dei vari salti.
Ho provato sia a compilare con gcc e basta (quindi fa qualche
ottimizzazione di default, ma poche) sia con gcc -O6 (tanto per
sparare un O-grande).
In entrambi i casi la struttura era quella: tabella di jump da una
parte e catena di test e salti dall'altra.
Naturalmente altre cose erano cambiate (quello che riesce a fare
un ottimizzatore e' sempre una cosa che mi riempie di meraviglia).
Per esempio aveva messo a parte il codice che invoca la funzione fun
e assegna il risultato alla variabile y, in modo da doverlo scrivere
una volta sola.
ciao,
g.

 un O-grande).
Non ho mai capito bene come si comporta il gcc con le opzioni del tipo 
-ON, se N non e' supportato ... La documentazione dice che la massima 
ottimizzazione si ottiene con -O3, puoi provare con quello, please?
 Grazie
 Federico


Io penso che se gli dai per esempio -O6 e 6 non l'ha usa il piu' grande
che ha. In effetti l'output con -O3 e -O6 e' uguale spiaccicato.
(non ho proprio l'ultimissima versione di gcc, comunque).
ciao,
g.

 Non e' propriamente vero.
 [...]
Grazie per la puntualizzazione! Non si finisce mai di imparare :) (del resto 
per questo avevo scritto: "da quello che so io")
Ciao 

 e' una cosa piu' rara da trovare e piu' dispendiosa da riconoscere,
A prima vista, nel caso generale, il riconoscimento mi sembra proprio
un problema non decidibile, quindi _dubito_ che qualcuno fara` mai una
cosa del genere. Qualche caso particolare potrebbe essere riconoscibile
su base sintattica, ma, come dici giustamente, e` _raro_ da trovare
e anche cosi` dubito che qualcuno perda tempo a farci ottimizzazioni!
Saluti,
Marco Pallante
-- 
To email me, remove the no_ and _spam from my address.

news.ngi.it
 ha scritto:

Un giochetto molto interessante con il costrutto switch e' la Duff's device:
         register n = (count + 7) / 8;      /* count > 0 assumed */
         switch (count % 8)
         {
         case 0:        do {  *to = *from++;
         case 7:              *to = *from++;
         case 6:              *to = *from++;
         case 5:              *to = *from++;
         case 4:              *to = *from++;
         case 3:              *to = *from++;
         case 2:              *to = *from++;
         case 1:              *to = *from++;
                            } while (--n > 0);
         }
Non so se e' possibile fare una cosa del genere con altri costrutti.
Poi, secondo me, quando fai delle macchine a stati e' molto piu' 
leggibile lo switch rispetto all'if else.
Ciao
Giuseppe