2011-11-04 6 views
6

Actualmente estoy usando una instrucción switch para manejar tipos de mensajes entrantes de los cuales hay 20 o más casos diferentes. Algunos de estos casos son órdenes de magnitud más probables que otros.¿Optimización de la declaración de cambio de Java con muchos casos?

es el compilador de punto de acceso capaz de optimizar el fin de examinar los casos para encontrar la manera correcta para ejecutar o debo estructurar mi código para que los casos más comunes aparecen en primer lugar:

switch(messageType) 
{ 
    case MOST_COMMON: 
     // handle it 
     break; 

... 
    case LEAST_COMMON: 
     // handle it 
     break; 
} 

Todos los casos son mutuamente excluyentes .

¿Sería mejor utilizar el patrón de estrategia y una búsqueda de mapa en el tipo de mensaje?

El rendimiento es la principal preocupación, ya que estoy manejando miles de mensajes por segundo y estoy tratando de reducir la creación de objetos y la sobrecarga de llamadas a métodos.

Muchas gracias,

Chris

Editar: Gracias por los punteros. messageType es un int con un rango estrecho de valores, por lo que parece que se compilará con el bytecode "tableswitch", por lo que no es necesario reordenar los casos.

parte pertinente del especificación JVM está aquí http://java.sun.com/docs/books/jvms/second_edition/html/Compiling.doc.html#14942

+1

La mayoría de los compiladores de IIRC manejan sentencias 'switch' en C y C++ con tablas de búsqueda. Java podría hacer lo mismo. Pero podría estar equivocado. – NullUserException

+0

posible duplicado de [Java: If vs. Switch] (http://stackoverflow.com/questions/1061101/java-if-vs-switch) –

+0

El JIT * debe * optimizar la ruta durante la ejecución. Diseñaría ambos mecanismos para ver con certeza. –

Respuesta

3

A menos que esté seguro de que esta sentencia switch está causando problemas de rendimiento, entonces yo sugeriría que se está optimizando de forma prematura. Además, mira the accepted answer to this question.

+0

Hola Mike, punto de toma :) Este código se refiere a unos pocos cientos de millones de eventos por día laborable y representa aproximadamente el 30% de los ciclos de CPU para el programa. Solo quería una opinión sobre el JIT antes de sumergirse en las especificaciones de JVM. – ChrisWhoCodes

3

Si los casos son enum valores o están densamente distribuidos int valores, entonces mucking con el orden no le ayudará una vez que el compilador JIT se inicie para convertirlo todo en una tabla de búsqueda.

Si utiliza conmutadores de cadenas Java7 o valores escasamente distribuidos, los más comunes deberían ir primero, ya que se convierten en un conjunto en cascada de if, como operaciones de prueba y bifurcación.

+0

con una cuerda Java7 interruptores será más lenta becuase que sin embargo se convierte en cascada 'si' al igual que las declaraciones que utilizará 'es igual a' en las cadenas eveluating – maks

+0

Hola Mike, el interruptor está en un int con un rango estrecho de valores, así que creo que la respuesta es tabla de búsqueda y no hay necesidad de reordenar las cláusulas. – ChrisWhoCodes

+0

@maks, creo que estoy de acuerdo. ¿Estás tratando de señalarme una parte de mi respuesta que es incorrecta o solo de comentar sobre los interruptores de cadena en general? –

1

Una instrucción de conmutación es una búsqueda para determinar a qué bloque de código desea saltar. No es una serie de verificaciones if/else y el orden en que se declaran los bloques no tiene impacto en el rendimiento. es decir, que son todos los valores de casos que se controlan por igual y de una vez.

Un pseudo código que lo mismo que (para una pequeña gama de valores int)

goto case_label[messageType.ordinal()]; 

Para un gran valor int oscila una estructura de tabla diferente se utiliza. (Supongo que es una tabla hash)

La CPU puede usar la predicción de bifurcación y si un caso es mucho más común que los demás, puede optimizar la ejecución de forma dinámica.

Cuestiones relacionadas