2008-11-05 10 views

Respuesta

88

La palabra clave final no aparece en el archivo de clase para las variables locales y los parámetros, por lo que no puede afectar el rendimiento del tiempo de ejecución. Su único uso es aclarar la intención de los codificadores de que la variable no se modifique (lo que muchos consideran una razón dudosa para su uso) y tratar con clases internas anónimas.

Existe una gran cantidad de argumentos sobre si el modificador final en el método en sí tiene alguna ganancia de rendimiento ya que los métodos estarán incluidos por el compilador de optimización en tiempo de ejecución de todos modos, independientemente del modificador. En este caso, también debería usarse solo para restringir la anulación del método.

+5

podría pensar que las variables/params finales podrían optimizarse como variables de bucle sin embargo ... pero un buen compilador/tiempo de ejecución debería ser capaz de resolver eso sin final de todos modos ... –

+8

He visto el compilador de Sun emitir bytecode ligeramente más corto cuando el único diff La diferencia entre los dos métodos ha sido la "finalidad" de las variables locales. Las micro-optimizaciones son reales, y los compiladores realmente las hacen. Lo que realmente importa, por supuesto, es qué hace el JIT con el bytecode, y las referencias locales pierden su "finalidad" cuando se compilan en bytecode. Creo que esta es la razón por la cual hay tanta especulación sobre las variables locales finales: es bastante determinista cuáles son los resultados. Sin embargo, el uso de locales finales puede afectar el bytecode, por lo que vale. –

+0

Como no es determinista, tampoco hay forma de depender de la optimización. Por supuesto, puede haber cambiado mucho en las implementaciones de VM desde la respuesta original en 2008 ;-) – Robin

1

Los compiladores que funcionan después de la carga de clases, como los compiladores JIT, pueden aprovechar los métodos finales. En consecuencia, los métodos declarados definitivos podrían tener algún beneficio en el rendimiento.

http://www.javaperformancetuning.com/tips/final.shtml

Ah, y otro buen recurso

http://mindprod.com/jgloss/final.html

+8

La pregunta era acerca de los parámetros que se declaran finales, lo que no tiene impacto en el rendimiento. – Robin

+0

En el JIT'S moderno (Hotspot) final no tiene ninguna influencia de rendimiento (mensurable), ya sea aplicada a los parámetros o la clase – kohlerm

+1

Los dos artículos que enlaza sugieren que la final es más bien una marca semántica para los desarrolladores, y que el JIT los compiladores pueden usar el final (pero como otros señalaron, realmente no necesitan esa información). Tan final es más bien semántico, lo que es paralelo a la capacidad moderna de los compiladores C/++ para inferir la constitud de variables y métodos, incluso si no están marcados const explícitamente. – ron

5

No puedo pensar en una razón por la cual el compilador le importaría si usted declaró un parámetro de método o no definitiva.

Pero la verdadera respuesta a esta pregunta es: escribir dos funciones, una con parámetros finales y otra con parámetros regulares. Ejecútelos un millón de veces cada uno y vea si hay alguna diferencia de tiempo de ejecución notable.

Si le preocupa el rendimiento, es muy importante hacer un trabajo de creación de perfiles sobre su código y averiguar exactamente qué es lo que le está ralentizando. Es casi seguro que no es lo que esperaría que fuera :)

+10

Eso no es una respuesta sino una conjetura y una guía sobre cómo obtener una respuesta empírica :-( – ordnungswidrig

14

El único beneficio para un parámetro final es que puede usarse en clases anónimas anidadas. Si un parámetro nunca se cambia, el compilador ya lo detectará como parte de su operación normal, incluso sin el modificador final. Es bastante raro que los errores sean causados ​​por la asignación inesperada de un parámetro: si sus métodos son lo suficientemente grandes como para necesitar este nivel de ingeniería, hágalos más pequeños, los métodos a los que llama no pueden cambiar sus parámetros.

+7

"Es bastante raro que los errores sean causados ​​por la asignación inesperada de un parámetro". Es más común de lo que piensas ... – RAY

+2

@RAY es posible que tenga razón, en realidad no tengo ningún dato (más allá de mi propia experiencia) para respaldar ese reclamo. –

+0

@DobesVandermeer para ser más preciso, eso no es realmente un "beneficio para un parámetro * final *". lo que está describiendo es simplemente la sintaxis requerida para cualquier variable local (del cual estoy incluyendo parámetros como) para hacerse visible para el alcance local de la clase anidada anónima. – swooby

0

Le sugiero que nunca escriba micro benchmarks. No sabe qué optimización puede hacer el JIT y cuándo, y es probable que tenga una idea equivocada de cómo se comporta simplemente haciendo un "caso de prueba simple"

+1

Bueno, puede ser, pero nadie aquí ha escrito o sugerido un microbenchmark ... – Kip

+3

@Mike La respuesta de Blandford sugiere usar un micro- punto de referencia, ¿no? –

+0

Escribir micro benchmarks en Java es algo muy complicado – Edmondo1984

0

Supongo que el compilador podría eliminar todas las variables finales estáticas privadas que tiene un tipo primitivo, como int, y los inserta directamente en el código al igual que con una macro de C++.

Sin embargo, no tengo ni idea si esto se hace en la práctica, pero podría hacerse para guardar algo de memoria.

0

Sólo un punto más que por encima de que el uso de variables locales no finales declarados en el método de la instancia de clase interior puede sobrevivir al marco de pila, por lo que la variable local podría desaparecer mientras que el objeto interno está todavía vivo

0

final parámetros de solo lectura (significa la identidad del objeto, no su estado).

Cuestiones relacionadas