Preocupado por el rendimiento de mi aplicación web, me pregunto cuál de las declaraciones "si / si no" o cambiar es mejor en cuanto al rendimiento.
123
Preocupado por el rendimiento de mi aplicación web, me pregunto cuál de las declaraciones "si / si no" o cambiar es mejor en cuanto al rendimiento.
if
etc.Respuestas:
Eso es micro optimización y optimización prematura, que son malas. Preocúpese más bien por la legibilidad y el mantenimiento del código en cuestión. Si hay más de dos
if/else
bloques pegados entre sí o su tamaño es impredecible, entonces puede considerar unaswitch
declaración.Alternativamente, también puede tomar Polimorfismo . Primero crea una interfaz:
Y hazte con todas las implementaciones en algunas
Map
. Puede hacer esto de forma estática o dinámica:Finalmente reemplace el
if/else
oswitch
por algo como esto (dejando a un lado los controles triviales como los punteros nulos):Se podría ser microslower de
if/else
oswitch
, pero el código es al menos mucho mejor mantener.Mientras habla de aplicaciones web, puede utilizarla
HttpServletRequest#getPathInfo()
como tecla de acción (eventualmente, escriba más código para dividir la última parte de pathinfo en un bucle hasta que se encuentre una acción). Aquí puede encontrar respuestas similares:Si le preocupa el rendimiento de la aplicación web Java EE en general, este artículo también puede resultarle útil. Hay otras áreas que brindan una ganancia de rendimiento mucho mayor que solo (micro) optimizar el código Java sin procesar.
fuente
Estoy totalmente de acuerdo con la opinión de que la optimización prematura es algo que se debe evitar.
Pero es cierto que Java VM tiene códigos de bytes especiales que podrían usarse para switch ().
Ver especificaciones de WM ( conmutador de búsqueda y conmutador de tabla )
Por lo tanto, podría haber algunas mejoras en el rendimiento, si el código es parte del gráfico de rendimiento de la CPU.
fuente
Es muy poco probable que un if / else o un switch sea la fuente de sus problemas de rendimiento. Si tiene problemas de rendimiento, primero debe realizar un análisis de perfil de rendimiento para determinar dónde están los puntos lentos. ¡La optimización temprana es la raíz de todo mal!
Sin embargo, es posible hablar sobre el rendimiento relativo de switch frente a if / else con las optimizaciones del compilador de Java. En primer lugar, tenga en cuenta que en Java, las sentencias switch operan en un dominio muy limitado: enteros. En general, puede ver una declaración de cambio de la siguiente manera:
donde
c_0
,,c_1
..., yc_N
son números<condition>
enteros que son destinos de la instrucción de cambio y deben resolverse en una expresión entera.Si este conjunto es "denso", es decir, (max (c i ) + 1 - min (c i )) / n> α, donde 0 <k <α <1, donde
k
es mayor que algún valor empírico, a Se puede generar una tabla de salto, que es muy eficiente.Si este conjunto no es muy denso, pero n> = β, un árbol de búsqueda binario puede encontrar el objetivo en O (2 * log (n)) que también es eficiente.
Para todos los demás casos, una instrucción switch es exactamente tan eficiente como la serie equivalente de declaraciones if / else. Los valores precisos de α y β dependen de varios factores y están determinados por el módulo de optimización de código del compilador.
Finalmente, por supuesto, si el dominio de
<condition>
no son los números enteros, una declaración de cambio es completamente inútil.fuente
¡Usa el interruptor!
¡Odio mantener bloqueos if-else! Hágase una prueba:
Mi código estándar de C # para la evaluación comparativa
fuente
switch
es?Recuerdo haber leído que hay 2 tipos de declaraciones Switch en el código de bytes de Java. (Creo que fue en 'Java Performance Tuning' One es una implementación muy rápida que usa los valores enteros de la declaración de cambio para conocer el desplazamiento del código que se ejecutará. Esto requeriría que todos los enteros sean consecutivos y en un rango bien definido Supongo que el uso de todos los valores de un Enum también entraría en esa categoría.
Sin embargo, estoy de acuerdo con muchos otros carteles ... puede ser prematuro preocuparse por esto, a menos que este sea un código muy, muy caliente.
fuente
switch
varias formas diferentes, algunas más eficientes que otras. En general, la eficiencia no será peor que una "if
escalera" sencilla , pero hay suficientes variaciones (especialmente con el JITC) que es difícil ser mucho más preciso que eso.Según Cliff Click en su charla Java One de 2009 Un curso intensivo en hardware moderno :
Puede obtener sus diapositivas completas aquí .
Cliff da un ejemplo (terminando en la diapositiva 30) que muestra que incluso con la CPU haciendo cambio de nombre de registro, predicción de rama y ejecución especulativa, solo puede iniciar 7 operaciones en 4 ciclos de reloj antes de tener que bloquear debido a dos fallas de caché que toman 300 ciclos de reloj para volver.
Entonces, él dice que para acelerar su programa, no debería estar mirando este tipo de problemas menores, sino más grandes, como si está haciendo conversiones de formato de datos innecesarias, como convertir "SOAP → XML → DOM → SQL → ... "que" pasa todos los datos a través de la caché ".
fuente
En mi prueba, el mejor rendimiento es ENUM> MAP> SWITCH> IF / ELSE IF en Windows7.
fuente
Time taken for String in Switch :3235 Time taken for String in if/else if :3143 Time taken for String in Map :4194 Time taken for String in ENUM :2866
Para la mayoría
switch
y la mayoría de losif-then-else
bloques, no puedo imaginar que haya preocupaciones importantes o apreciables relacionadas con el rendimiento.Pero aquí está la cuestión: si está utilizando un
switch
bloque, su uso sugiere que está activando un valor tomado de un conjunto de constantes conocidas en tiempo de compilación. En este caso, realmente no debería usarswitch
declaraciones si puede usar unenum
con métodos específicos de constante.En comparación con una
switch
declaración, una enumeración proporciona una mejor seguridad de tipos y un código que es más fácil de mantener. Las enumeraciones se pueden diseñar de modo que si se agrega una constante al conjunto de constantes, su código no se compilará sin proporcionar un método específico de constante para el nuevo valor. Por otro lado, olvidar agregar un nuevocase
a unswitch
bloque a veces solo se puede detectar en el tiempo de ejecución si tiene la suerte de haber configurado su bloque para lanzar una excepción.Rendimiento entre
switch
unenum
método específico de constante y no debería ser significativamente diferente, pero este último es más legible, más seguro y más fácil de mantener.fuente