Como reflexión ... en caso de que uno se quede atrapado con un compilador viejo/defectuoso/ineficiente o simplemente adore la piratería.
El trabajo interno de switch
declaración consta de dos partes. Encontrar la dirección para saltar, y saltar bien allí. Para la primera parte necesita usar una tabla para encontrar la dirección. Si aumenta el número de casos, la tabla se hace más grande: la búsqueda de la dirección para saltar lleva tiempo. Este es el punto que los compiladores intentan optimizar, combinando varias técnicas, pero un enfoque fácil es usar la tabla directamente, que depende del espacio de valor de caso.
En una parte posterior del ejemplo de la servilleta;
switch (n) {
case 1: foo(); break;
case 2: bar(); break;
case 3: baz(); break;
}
con tal pieza de compilador de código puede crear una matriz de jump_addresses y directamente obtener la dirección de array [n]. Ahora la búsqueda acaba de tomar O (1). Pero si tuviera un interruptor, como a continuación:
switch (n) {
case 10: foo(); break;
case 17: bar(); break;
case 23: baz(); break;
// and a lot other
}
compilador necesita para generar una tabla que contiene CASE_ID, pares jump_address y el código para buscar a través de esa estructura que la peor aplicación puede tomar O (n). (Los compiladores decentes optimizan el infierno de tal escenario cuando se desencadenan completamente habilitando sus indicadores de optimización en un grado tal que cuando necesite depurar dicho código optimizado su cerebro empiece a freír).
Entonces, ¿se puede hacer esta pregunta? todo usted mismo en el nivel C para vencer al compilador? y lo curioso es que al crear tablas y buscarlas parece fácil, saltar a un punto variable usando goto
no es posible en el estándar C. Entonces existe la posibilidad de que si no va a utilizar punteros a función debido a la estructura de código o sobrecarga, estás atascado ... bueno si no estás usando GCC
. GCC tiene una función no estándar llamada Labels as Values que le ayuda a obtener punteros a las etiquetas.
Para completar el ejemplo, se puede escribir la segunda sentencia switch con "etiquetas como valores" característica de esta manera:
const void *cases[] = {&&case_foo, &&case_bar, &&case_baz, ....};
goto *labels[n];
case_foo:
foo();
goto switch_end;
case_bar:
bar();
goto switch_end;
case_baz:
baz();
goto switch_end;
// and a lot other
switch_end:
Por supuesto, si usted está hablando cerca de 5000 casos, es mucho mejor si se escribe una una pieza de código para crear este código para usted, y probablemente sea la única forma de mantener dicho software.
Como notas de cierre; ¿Esto mejorará tu trabajo diario? No. ¿Esto mejorará tus habilidades? Sí, y hablando por experiencia, una vez descubrí que mejoraba un algoritmo de seguridad en una tarjeta inteligente simplemente optimizando los valores de los casos. Es un mundo extraño.
¿Por qué le gustaría comparar 5000 casos? ¿No puedes comprimir/refactorizar el código para que tengas menos casos en cada segmento de código? – mmoment
Puede usar ** una serie de indicadores de funciones **, es mucho más rápido que cualquier comparación PERO mi pregunta es ... ¿cómo puede ** administrar y mantener ** el código con una instrucción 'switch/case' con 5000 casos ? –
Si necesita cambiar entre 5000 casos, parece una mala intención de diseño. De lo contrario, iría por punteros de función también. – dtech