estudiar más en detalle Jerry's answer y otros
Dado:
int x=1;
switch (i) {
case 1: x=6; break;
case 2: x++;
// Fall through
case 3: x+=7; break;
}
que podría tener algo como lo siguiente:
int f1() {return 6;}
int f2() {return 1+f3();}
int f3() {return 8;}
El compilador podría utilizar una tabla de saltos para indexar {f1, f2, f3}
El compilador puede hacer inlining al crear la tabla que tiene f1, f2, f3
estableciendo x
directamente a 6,9,8
Pero si usted escribió las funciones, y rodó su propia tabla de saltos, f1,f2,f3
podría estar en cualquier lugar, pero el compilador sabrá ponerlos cerca de la switch
crear mucho mejor código localidad de lo que podría.
Tenga en cuenta que en muchos casos el compilador generará un guardia para comprobar si i
está en el rango (o manejar la default
) y si está seguro de que siempre es uno de los casos, usted podría saltar esa
lo interesante es que por debajo de un pequeño número de casos, y bajo diferentes parámetros del compilador (compilador dependiente) la switch
no necesita usar una tabla, sino que sólo lo hacen IFS, similar a:
if (i==1) x=f1();
else if (i==2) x=f2();
else if (i==3) x=f3();
o podría optimice esto (donde las pruebas simples son una instrucción) a:
x=(i==1) ? f1()
: (i==2) ? f2()
: (i==3) ? f3()
: x;
El mejor consejo es buscar en el conjunto generado para ver lo que el compilador hizo a tu código en su arquitectura, g ++ en Linux/Intel va a generar algo como lo siguiente, si hay una tabla de saltos
(nota que tenía que ir a 5 case
declaraciones para forzar la tabla de saltos, se utilizan IFS por debajo de ese número de case
declaraciones)
Tenga en cuenta que los pequeños agujeros estarán en la tabla de saltos para hacer el default
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;
}
generaría el siguiente código ensamblador (// comentarios son míos):
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
Por lo general, un "diccionario" es lo mismo que una tabla hash. –