Trying to upgrade to JDK8 on a big project, compilation goes really slow on JDK8 compared to JDK7.
Running the compiler in verbose mode, JDK8 compiler stops at a big generated converter class(Mapping) for entities from server to client. The converter methods in several cases call other converter methods from the same Mapping class.
As a workaround tried to split the Mapping file into multiple files. This visibly improved performance when only compiling the Mapping class or it's containing project(projectA). But compile time was very slow for other projects which invoke converter methods from projectA.
Another workaround was to make all convert methods return null, not calling anything else. Again, the performance was good for projectA but not for depending projects.
ProjectA uses generics but since it is compatible with JDK6, which didn't have generalized type inference introduced, maybe it's another JDK8 bug that causes this slowdown.
So possibly out of context but for generalized type inference, some threads like below suggest an upgrade to JDK9. But since it's not yet released, it's not a viable option as upgrade. It'd be ideal if a backport of the fix would be done to JDK8. This was requested in the following StackOverflow thread but no reply from Oracle team yet.
Slow compilation with jOOQ 3.6+, plain SQL, and the javac compiler
I've attached 2 screenshots of how the heap looks in JDK7 vs JDK8. Could this be a cause for the JDK8 slowdown?
Thank you!
Update 20160314
The converter methods from Mapping class look like:
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;
}
And the VO looks like:
public class ResponseItemVO extends ResultVO<IdentifierVO, DetailsVO > {
public ResponseItemVO() {}
}
You've noticed already, there's a severe performance regression in Java 8 when it comes to overload resolution based on generic target typing. One of the reasons in your case might be the fact that the compiler needs to find the appropriate method from an assignment type
If you're in control of the code generator, and not constrained by backwards compatibility, it might be worth thinking about avoiding the overloading of the
convert()
method. Without overloading, the compiler doesn't have to do the overload resolution work, neither inside of your mapping code, nor at the call site. This will certainly be much much faster.Attempt 1: By using the parameter type in the method name:
Attempt 2: By moving the convert method elsewhere, e.g. into the
VO
typeOr better...