new icon example borderfactory java compilation java-8 compiler-optimization

java - icon - compilación lenta JDK8



my icon java (1)

Al tratar de actualizar a JDK8 en un gran proyecto, la compilación es muy lenta en JDK8 en comparación con JDK7.

Al ejecutar el compilador en modo detallado, el compilador JDK8 se detiene en una gran clase de conversores generados (Mapping) para entidades de servidor a cliente. Los métodos de conversión en muchos casos llaman a otros métodos de conversión de la misma clase de asignación.

Como solución alternativa, intentó dividir el archivo de asignación en varios archivos. Esto mejora visiblemente el rendimiento cuando solo se compila la clase Mapping o contiene proyectos (projectA). Pero el tiempo de compilación fue muy lento para otros proyectos que invocan métodos de conversión de projectA.

Otra solución fue hacer que todos los métodos de conversión devuelvan nulo, sin llamar a nada más. Una vez más, el rendimiento fue bueno para projectA pero no para proyectos dependientes.

ProjectA utiliza genéricos, pero dado que es compatible con JDK6, que no presentó inferencia de tipo generalizada, tal vez sea otro error de JDK8 el que cause esta desaceleración.

Por lo tanto, posiblemente fuera de contexto, pero para la inferencia de tipo generalizada, algunos subprocesos como los que se muestran a continuación sugieren una actualización a JDK9. Pero dado que aún no se ha lanzado, no es una opción viable como la actualización. Sería ideal si se hiciera un respaldo de la solución a JDK8. Esto se solicitó en el siguiente subproceso de StackOverflow pero aún no se recibió respuesta del equipo de Oracle.

Compilación lenta con jOOQ 3.6+, SQL simple y el compilador javac

He adjuntado 2 capturas de pantalla de cómo se ve el montón en JDK7 vs JDK8. ¿Podría ser esto una causa de la desaceleración de JDK8?

¡Gracias!

Actualización 20160314

Los métodos de conversión de la clase Mapeo se ven así:

public static ResponseItemVO convert (ResponseItem pArg0){ if(pArg0==null){ return null; } ResponseItemVO ret = new ResponseItemVO(); ret.setErrorDetails(pArg0.getErrorDetails()); ret.setResult(Mapping.convert(pArg0.getResult())); ret.setIdentifier(Mapping.convert(pArg0.getIdentifier())); return ret; }

Y el VO se ve así:

public class ResponseItemVO extends ResultVO<IdentifierVO, DetailsVO > { public ResponseItemVO() {} }

JDK7 Heap: JDK8 Heap:


Ya lo ha notado, hay una regresión de rendimiento severa en Java 8 cuando se trata de una resolución de sobrecarga basada en la tipificación genérica de objetivos. Una de las razones en su caso podría ser el hecho de que el compilador necesita encontrar el método apropiado a partir de un tipo de asignación

ResultVO<Something, Something> result = Mapping.convert(...); // heavy lookup here ---------------------------^^^^^^^

Si tiene el control del generador de código y no está limitado por la compatibilidad con versiones anteriores, podría valer la pena pensar en evitar la sobrecarga del método convert() . Sin sobrecargar, el compilador no tiene que hacer el trabajo de resolución de sobrecarga, ni dentro del código de asignación, ni en el sitio de la llamada. Esto sin duda será mucho más rápido.

Intento 1: Al usar el tipo de parámetro en el nombre del método:

class Mapping { public static ResponseItemVO convertResponseItem(ResponseItem pArg0){ if (pArg0==null){ return null; } ResponseItemVO ret = new ResponseItemVO(); ret.setErrorDetails(pArg0.getErrorDetails()); ret.setResult(Mapping.convertResult(pArg0.getResult())); ret.setIdentifier(Mapping.convertIdentifier(pArg0.getIdentifier())); return ret; } }

Intento 2: moviendo el método de conversión a otra parte, p. Ej. Al tipo de VO

class ResponseItemVO { public static ResponseItemVO from(ResponseItem pArg0){ if (pArg0==null){ return null; } ResponseItemVO ret = new ResponseItemVO(); ret.setErrorDetails(pArg0.getErrorDetails()); ret.setResult(ResultVO.from(pArg0.getResult())); ret.setIdentifier(IdentifierVO.from(pArg0.getIdentifier())); return ret; } }

O mejor...

class ResponseItem { public ResponseItemVO toVO(){ ResponseItemVO ret = new ResponseItemVO(); ret.setErrorDetails(getErrorDetails()); ret.setResult(getResult().toVO()); ret.setIdentifier(getIdentifier().toVO()); return ret; } }