weiter zu erarbeiten auf Jerry's answer und andere
Gegeben:
int x=1;
switch (i) {
case 1: x=6; break;
case 2: x++;
// Fall through
case 3: x+=7; break;
}
Sie könnte so etwas wie die folgenden:
int f1() {return 6;}
int f2() {return 1+f3();}
int f3() {return 8;}
Der der Compiler eine Sprungtabelle zu indizieren verwenden könnte {f1, f2, f3}
Der Compiler kann inlining wenn Erstellen der Tabelle mit f1, f2, f3
x
direkt an 6,9,8
Einstellung Aber wenn Sie die Funktionen geschrieben, und Ihre eigenen Sprungtabelle gerollt, f1,f2,f3
könnte überall sein, aber der Compiler wissen sie in der Nähe der switch
viel besser zu schaffen setzen Code-Ort als Sie könnten.
Beachten Sie, dass in vielen Fällen der Compiler eine Wache generieren zu überprüfen, ob i
in Reichweite ist (oder die default
zu behandeln), und wenn Sie sicher sind, dass es immer eine der Fälle ist, könnten Sie überspringen, dass
das interessante daran ist, dass für die unter einer kleinen Anzahl von Fällen und unter verschiedenem Compiler-Flags (Compiler-abhängig) die switch
keine Tabelle verwenden würde, würde aber ifs nur tun, ähnlich wie:
if (i==1) x=f1();
else if (i==2) x=f2();
else if (i==3) x=f3();
oder es könnte Optimiere dies (wobei einfache Tests eine Anweisung sind) an:
x=(i==1) ? f1()
: (i==2) ? f2()
: (i==3) ? f3()
: x;
Der beste Rat ist bei der Montage sehen erzeugt, um zu sehen, was der Compiler den Code auf Ihrer Architektur haben, g ++ auf Linux/Intel etwas wie die folgende erzeugen wird, wenn es eine Sprungtabelle ist
(note I bis 5 case
Aussagen gehen musste die Sprungtabelle zu zwingen, verwendet es ifs unterhalb dieser Anzahl von case
Aussagen)
Beachten sie, dass kleine Löcher in der Sprungtabelle wird die default
zu tun
int foo(int i)
{
int x=1;
switch (i) {
case 1: x=6; break;
case 2: x++;
// Fall through
case 3: x+=7; break;
case 4: x+=2; break;
case 5: x+=9; break;
}
return x;
}
den folgenden Assembler-Code generieren würde (// Kommentare sind Mine):
cmp edi, 5 //make sure it is not over 5
ja .L2 //jump to default case
mov edi, edi
jmp [QWORD PTR .L4[0+rdi*8]] // use the jump table at label L4:
.L4:
.quad .L2 // if i=0, set x=1 (default)
.quad .L9 // f1() see below
.quad .L10 // f2() see below
.quad .L6 // f3() see below
.quad .L7 // f4() see below
.quad .L8 // f5() see below
.L10:
mov eax, 9 // x=9
ret
.L9:
mov eax, 6 // x=6
ret
.L8:
mov eax, 10 // x=10
ret
.L6:
mov eax, 8 // x=8
ret
.L7:
mov eax, 3 // x=3
ret
.L2:
mov eax, 1 // default, x was 1, noop is: x=1
ret
Normalerweise ist ein "Wörterbuch" dasselbe wie eine Hashtabelle. –