Optimización por el comstackdor de Java

Recientemente, estaba leyendo este artículo .

De acuerdo con ese artículo, Java Compiler, es decir, javac no realiza ninguna optimización al generar bytecode. ¿Es realmente cierto? Si es así, ¿puede implementarse como un generador de código intermedio para eliminar la redundancia y generar un código óptimo?

javac solo hará una optimización muy pequeña, si hay alguna.

El punto es que el comstackdor de JIT hace la mayor parte de la optimización, y funciona mejor si tiene mucha información, parte de la cual puede perderse si javac realiza la optimización. Si javac realizara algún tipo de desenrollado de bucle, sería más difícil para el JIT hacerlo de forma general, y tiene más información sobre qué optimizaciones realmente funcionarán, ya que conoce la plataforma de destino.

Dejé de leer cuando llegué a esta sección:

Más importante aún, el comstackdor javac no realiza optimizaciones simples como el despliegue de bucles, la simplificación algebraica, la reducción de la resistencia y otros. Para obtener estos beneficios y otras optimizaciones simples, el progtwigdor debe realizarlos en el código fuente de Java y no depender del comstackdor javac para realizarlos.

En primer lugar, realizar bucles de desenrollado en código fuente Java casi nunca es una buena idea. La razón por la cual javac no hace mucho en cuanto a la optimización es que lo hace el comstackdor JIT en la JVM, que puede tomar mejores decisiones que el comstackdor, ya que puede ver exactamente qué código se está ejecutando más.

El comstackdor javac una vez admitió una opción para generar bytecode optimizado pasando -o en la línea de comando.

Sin embargo, a partir de J2SE1.3, HotSpot JVM se envió con la plataforma , que introdujo técnicas dinámicas como la comstackción justo a tiempo y la optimización adaptativa de las rutas de ejecución comunes. Por lo tanto, el comstackdor de Java ignoró -o iniciando esta versión.

Encontré esta bandera cuando leí sobre la tarea Ant javac y su atributo optimize :

Indica si la fuente debe comstackrse con optimización; se off por defecto Tenga en cuenta que este indicador solo es ignorado por el javac de Sun que comienza con JDK 1.3 (ya que la optimización en tiempo de comstackción no es necesaria).

Las ventajas de las optimizaciones dinámicas de HotSpot JVM sobre la optimización en tiempo de comstackción se mencionan en esta página :

Server VM contiene un comstackdor adaptativo avanzado que admite muchos de los mismos tipos de optimizaciones realizadas optimizando los comstackdores de C ++, así como algunas optimizaciones que los comstackdores tradicionales no pueden realizar, como una alineación agresiva en las invocaciones de métodos virtuales. Esta es una ventaja competitiva y de rendimiento sobre los comstackdores estáticos. La tecnología de optimización adaptable es muy flexible en su enfoque, y generalmente supera incluso el análisis estático avanzado y las técnicas de comstackción.

Estudié el bytecode de salida de Java en el pasado (usando una aplicación llamada FrontEnd). Básicamente no hace ninguna optimización, excepto para las constantes de alineación (finales estáticos) y las expresiones fijas de precalculación (como 2 * 5 y “ab” + “cd”). Esto es parte de por qué es tan fácil de desmontar (usando una aplicación llamada JAD)

También descubrí algunos puntos interesantes para optimizar tu código java. Me ayudó a mejorar la velocidad de los bucles internos en 2,5 veces.

Un método tiene 5 variables de acceso rápido. Cuando se invocan estas variables, son más rápidas que todas las demás variables (probablemente debido al mantenimiento de la stack). Los parámetros de un método también se cuentan para estos 5. Por lo tanto, si tiene un código dentro de bucle que se ejecuta como un millón de veces, asigne esas variables al inicio del método y no tenga parámetros.

Las variables locales también son más rápidas que los campos, por lo que si usa campos dentro de los bucles internos, guarde en caché estas variables asignándolas a una variable local al inicio del método. Caché la referencia, no los contenidos. (como: int [] px = this.pixels;)

Para optimizar su bytecode, puede usar Proguard .

Como han señalado otros, el JIT en una JVM convencional optimizará el código a medida que lo comstack y, como tiene acceso a más contexto, probablemente superará a Proguard. Este puede no ser el caso en máquinas virtuales más simples. En el mundo de Android, es una práctica común utilizar optimizaciones de Proguard cuando se dirige a Dalvik (la máquina virtual que viene con Android antes de Lollipop).

Proguard también reduce y ofusca el bytecode, que es imprescindible cuando se envían aplicaciones del lado del cliente (incluso si no se utilizan las optimizaciones).