76 votos

Si frente a la velocidad del interruptor

Las sentencias switch suelen ser más rápidas que las sentencias if-else-if equivalentes (como se describe, por ejemplo, en este artículo ) debido a las optimizaciones del compilador.

¿Cómo funciona realmente esta optimización? ¿Alguien tiene una buena explicación?

134voto

Konrad Rudolph Puntos 231505

El compilador puede construir tablas de salto cuando sea necesario. Por ejemplo, cuando utilices el reflector para ver el código producido, verás que para las grandes conmutaciones sobre cadenas, el compilador generará en realidad un código que utiliza una tabla hash para despacharlas. La tabla hash utiliza las cadenas como claves y delega en el case códigos como valores.

Esto tiene un tiempo de ejecución asintóticamente mejor que el de un montón de cadenas de if y es realmente más rápido incluso para relativamente pocas cadenas.

19voto

Crashworks Puntos 22920

Konrad es correcto. En el caso de la conmutación en rangos contiguos de enteros (por ejemplo, donde se tiene el caso 0, el caso 1, el caso 2 .. el caso n), el compilador puede hacer algo aún mejor porque ni siquiera necesita construir una tabla hash; simplemente almacena un Array de punteros de función, y así puede cargar su objetivo de salto en tiempo constante.

10voto

olliej Puntos 16255

Se trata de una ligera simplificación, ya que normalmente cualquier compilador moderno que encuentra un if..else if .. que podría convertirse trivialmente en una sentencia switch por una persona, el compilador también lo hará. Pero para añadir más diversión, el compilador no está restringido por la sintaxis, por lo que puede generar internamente sentencias tipo "switch" que tengan una mezcla de rangos, objetivos únicos, etc., y puede (y lo hace) hacer esto tanto para las sentencias switch como para las if..else.

En cualquier caso, una extensión de la respuesta de Konrad es que el compilador puede generar una tabla de saltos, pero eso no está necesariamente garantizado (ni es deseable). Por diversas razones, las tablas de saltos perjudican a los predictores de bifurcación de los procesadores modernos, y las propias tablas perjudican el comportamiento de la caché, por ejemplo.

switch(a) { case 0: ...; break; case 1: ...; break; }

Si un compilador generara realmente una tabla de saltos para esto, probablemente sería más lento que la alternativa if..else if.. debido a que la tabla de saltos anula la predicción de bifurcaciones.

4voto

J.J. Puntos 3543

Como dijo Konrad, el compilador puede construir una tabla de salto.

En C++ una razón por la que se puede es por la limitación de los interruptores.

3voto

Calyth Puntos 1368

Las estadísticas de los no-partidos pueden no ser buenas.

Si realmente se descarga el código fuente, se sabe que los valores de no coincidencia son 21, tanto en el caso de if como de switch. Un compilador debería ser capaz de abstraerse, sabiendo qué declaración debe ejecutarse en todo momento, y una CPU debería ser capaz de predecir la bifurcación correctamente.

El caso más interesante es cuando no todos los casos se rompen, en mi opinión, pero puede que ese no haya sido el alcance del experimento.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X