tabla quién que programacion maquina interprete estructura ejemplos codigo java optimization micro-optimization

java - quién - tabla de codigo bytecode



¿Los finales de Java ayudan al compilador a crear un bytecode más eficiente? (4)

El uso de final no otorga ningún beneficio de rendimiento. Tienes que recurrir a JNI por motivos de rendimiento. Dicho esto, es aconsejable utilizar mejores JVM que optimicen el bytecode por sí mismas (p. Ej., El tiempo de ejecución integrado de eclipse es más eficiente que el estándar) y pongan más énfasis en su código.

Posible duplicado:
¿El uso de la palabra clave final en Java mejora el rendimiento?

El modificador final tiene diferentes consecuencias en Java, dependiendo de a qué lo aplique. Lo que me pregunto es si, además , podría ayudar al compilador a crear un bytecode más eficiente. Supongo que la pregunta profundiza en cómo funciona la JVM y podría ser específica de JVM.

Entonces, en su experiencia, ¿alguno de los siguientes ayuda al compilador, o solo los usa por las razones normales de Java?

  • Clases finales
  • Métodos finales
  • Campos finales
  • Argumentos del método final

¡Gracias!

EDIT: gracias por todas sus respuestas! Tenga en cuenta que, como sugirió @Zohaib, mi pregunta es un duplicado de esto . No busqué lo suficiente antes de publicar. No lo borro porque ustedes hicieron buenas contribuciones, pero las respuestas podrían fusionarse. Dejaré que el sistema de "votación para cerrar" decida a menos que se indique lo contrario.


Esa pregunta ya se ha formulado bastante y la respuesta generalmente es: el compilador podría hacer algunas optimizaciones (por ejemplo, constantes en línea que son campos estáticos finales) pero generalmente no debería molestarse con esto, ya que esas ganancias de rendimiento podrían no ser notorias. . Solo use la palabra clave final para los motivos "normales" de Java (haga que los campos o parámetros sean inmutables, evite la creación de subclases o la anulación de métodos).


Sugiero que lo pruebes con tu código. Puede hacer una diferencia con el compilador en algunos casos, sin embargo, es más probable que haga una diferencia en el JIT. Cuando se trata de micro-benchmarks y micro-tuning, lo que debería marcar la diferencia y lo que realmente hace la diferencia a menudo no es lo mismo y solo una buena prueba es la manera de estar seguro.

Otro problema que tienes es que la JVM está mejorando todo el tiempo y es posible que un truco que marcó una gran diferencia antes no se aplique. por ejemplo, en Java 5.0 Lock fue mucho más rápido que synchronized sin embargo, en Java 6, la diferencia es mucho menor y la synchronized puede ser más rápida.

En general, es una buena idea hacer que su código sea simple, claro y fácil de mantener, y esto también dará como resultado un código eficiente.


Los códigos de bytes no son significativamente más o menos eficientes si utiliza final porque los compiladores de código de bytes de Java normalmente hacen poco en la optimización del camino. La bonificación de eficiencia (si corresponde) estará en el código nativo producido por el compilador JIT.

En teoría, usar el final proporciona una pista al compilador de JIT que debería ayudarlo a optimizar. En la práctica, los compiladores HotSpot JIT recientes pueden hacer un mejor trabajo al ignorar sus sugerencias. Por ejemplo, un compilador JIT moderno generalmente realiza un análisis global para descubrir si una llamada a un método dado es una llamada a un método de hoja en el contexto de las clases actualmente cargadas de la aplicación. Este análisis es más preciso de lo que pueden ser sus sugerencias final , y el tiempo de ejecución incluso puede detectar cuándo se carga una nueva clase que invalida el análisis ... y rehace el análisis y la generación de código nativo para el código afectado.

Entonces, la mejor práctica es usar final para (en términos generales) expresar sus intenciones de diseño y lograr otros efectos semánticos que requiera. (Por ejemplo, el uso del modificador final puede jugar un papel importante en la implementación de tipos inmutables seguros para subprocesos, consulte JLS 17.5 ). Si utiliza el final como una sugerencia de optimización, no logrará mucho y hará que su código sea más difícil de modificar y ampliar.

ACTUALIZAR

Hay un par de excepciones a esto (como se señala a continuación):

  • En determinadas circunstancias, declarar un campo como final cambia la forma en que lo maneja el compilador de códigos de bytes. He dado un ejemplo arriba. Otro es el caso de la "variable constante" ( JLS 4.12.4 ) donde el valor del campo static final será subrayado por el compilador de códigos de bytes tanto en las clases actuales como en otras clases, y esto puede afectar el comportamiento observado del código. (Por ejemplo, hacer referencia a una variable constante NO provocará la inicialización de la clase. Por lo tanto, la adición de una final puede cambiar el orden de inicialización de la clase).

  • Es concebible que declarar un parámetro local o de campo como final permita una optimización menor del compilador JIT que de otro modo no se haría. Sin embargo, cualquier campo que se pueda declarar como final también se puede inferir como efectivamente final por el compilador JIT. (No está claro si el compilador JIT hace esto, y si eso afecta el código nativo generado).

Sin embargo, mi consejo anterior se aplica. Use el final para expresar sus intenciones de diseño, no como una sugerencia de optimización.