2011-09-17 24 views
5

tenía curiosidad, veo este tipo de cosas mucho:¿El compilador JDK optimiza el uso de clases anónimas sin variables de instancia?

Arrays.sort(array, new Comparator<Integer>() { 
    public int compare(Integer a, Integer b) { 
     return Math.abs(a) < Math.abs(b); 
    } 
}); 

ya que la clase anónima creada aquí no tiene variables de instancia, es el compilador JDK estándar lo suficientemente inteligente como para solamente una instancia de esa clase en el anonimato de una vez y reutilizarlo ? ¿O es aconsejable crear una instancia de esa clase anónima en un campo estático y pasar siempre el objeto comparador estático?

ACTUALIZACIÓN: Cuando digo "compilador JDK", me refiero a la parte JIT también. Lo anterior también es solo un ejemplo. Tenía mucha curiosidad si, como buena práctica, creara campos estáticos para lo anterior en lugar de crear instancias de clase anónimas. En algunos casos, el problema de rendimiento/uso de recursos será insignificante. Pero otros casos podrían no ser ...

Respuesta

3

javac definitivamente no hacer tal cosa; eso violaría la semántica del lenguaje. JVM podría optimizarlo en teoría, pero aún no es tan inteligente. Una estática sería más rápida.

Irónicamente, dicho análisis y optimización sería fácil para javac, y se puede hacer hoy, excepto que está prohibido hacerlo: la fuente dice new, por lo que javac debe new.

rumores de que la expresión lambda viene en Java 8 a hacer un esfuerzo en este tema, en

Arrays.sort(array, (Integer a,Integer b) => Math.abs(a)<Math.abs(b)) 

javac es necesario analizar que el lambda es sin estado, y una sola instancia con pereza creada es lo suficientemente , y eso es en lo que debe compilar el código.

0

Puede usar javap para comprobarlo usted mismo; mi sospecha es que lo creará en cada llamada. Dichas optimizaciones se manejan mediante un punto de acceso público, pero en este caso, dado que el anónimo solo tiene métodos (no hay campos para inicializar), la sobrecarga es muy pequeña.

1

La respuesta es tal vez.

javac compilará esto en bytecode que sea fiel a su código. Por lo tanto, la clase será instanciada de nuevo cada vez que se llame a este código. Sin embargo, la JVM realiza muchas optimizaciones sofisticadas en tiempo de ejecución, y MIGHT, dependiendo de muchos factores, puede realizar algunas optimizaciones aquí.

En cualquier caso, a menos que hayas notado un problema de rendimiento real aquí, te recomendaría no intentar optimizarlo manualmente.

0

La verdadera pregunta aquí no es qué hará javac. Como dice Steve McLeod, javac producirá bytecode que coincide con su código fuente. La pregunta es qué hará el punto de acceso en tiempo de ejecución. Me imagino que será simple en línea todo el lote (incluida la llamada Math.abs()).

0

El compilador realiza muy poca optimización. El jit hace la mayor parte. Optimiza este código, pero no evitará la creación de objetos enteros y, a menos que tengas una matriz de enteros, este será tu cuello de botella. Tanto que cualquier otra optimización que haga no importará.

Cuestiones relacionadas