Joaquín, miembro de nuestro equipo de trabajo, nos ha hecho el favor de escribir este enunciado ya que conoce muy bien dicho tema.
Solución:
Depende de lo que haga foo.getLength(). Si puede estar en línea, puede ser efectivamente lo mismo. Si no se puede alinear, la JVM no puede determinar si el resultado es el mismo.
Por cierto, puedes escribir para una sola línea.
for(int i = 0, length = foo.getLength(); i < length; i++)
EDITAR: No vale nada eso;
- los métodos y los bucles normalmente no se optimizan hasta que se han llamado 10.000 veces.
- perfiladores de invocaciones de submuestra para reducir la sobrecarga. Pueden contar cada 10 o 100 o más, por lo que es posible que no aparezca un ejemplo trivial.
Hice algunas pruebas en Java y parece que, por defecto, el índice y el límite se recalculan cada vez.
Según la especificación del lenguaje Java, esto:
for(int i = 0 ; i < foo.getLength() ; i++)
significa que getLength()
se llama en cada iteración del bucle. Los compiladores de Java son solo permitido para mover el getLength()
llamar fuera del circuito si pueden efectivamente probar que no altera el comportamiento observable.
(Por ejemplo, si getLength()
simplemente devuelve el valor de alguna variable, entonces existe la posibilidad de que el compilador JIT pueda alinear la llamada. Si después de incrustar puede deducir que la variable no cambiará (bajo ciertas suposiciones) puede aplicar una optimización de elevación. Por otro lado, si getLength()
implica obtener la longitud de una colección concurrente o sincronizada, las posibilidades son escasas o nulas de que se permita la optimización de elevación... debido a las posibles acciones de otros subprocesos).
Así que eso es lo que es un compilador permitido que hacer.
Me pregunto si es posible activar este tipo de función en JVM HotSpot.
La respuesta simple es no.
Parece que está sugiriendo un cambio de compilador que le dice/permite que el compilador ignore las reglas de JLS. No hay tal interruptor. Tal cambio sería un MALA IDEA. Es posible que provoque la ruptura de programas correctos/válidos/que funcionen. Considera esto:
class Test
int count;
int test(String[] arg)
for (int i = 0; i < getLength(arg); i++)
// ...
return count;
int getLength(String[] arg)
count++;
return arg.length;
Si al compilador se le permitiera mover el getLength(arg)
llamar fuera del bucle, cambiaría la cantidad de veces que se llamó al método y, por lo tanto, cambiaría el valor devuelto por el test
método.
Las optimizaciones de Java que cambian el comportamiento de un programa Java correctamente escrito no son optimizaciones válidas. (Tenga en cuenta que los subprocesos múltiples tienden a enturbiar las aguas. El JLS, y específicamente las reglas del modelo de memoria, permiten que un compilador realice optimizaciones que podrían dar como resultado que diferentes subprocesos vean versiones inconsistentes del estado de la aplicación... si no se sincronizan correctamente, lo que da como resultado un comportamiento incorrecto desde la perspectiva del desarrollador. Pero el verdadero problema está en la aplicación, no en el compilador).
Por cierto, un más convincente La razón por la que no debe cambiar la variable de bucle en el cuerpo del bucle es que hace que su código sea más difícil de entender.
La razón principal para no hacerlo es que hace mucho más difícil entender y mantener el código.
Independientemente de lo que optimice la JVM, no comprometerá la corrección del programa. Si no puede realizar una optimización porque el índice se modifica dentro del ciclo, entonces no lo optimizará. No veo cómo una prueba de Java podría mostrar si existe o no tal optimización.
De todos modos, Hotspot optimizará muchas cosas para ti. Y su segundo ejemplo es un tipo de optimización explícita que Hotspot hará felizmente por usted.
valoraciones y reseñas
Agradecemos que desees animar nuestro estudio dejando un comentario o dejando una valoración te damos la bienvenida.