Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Troubleshoot slow compilation

Tags:

What should I do to investigate and troubleshoot a slow compilation problem?

My project has about 100 classes and takes more than 45 seconds to compile, which seems very slow to me. As a reference, I have another project with 50 classes that compiles in 3 seconds.

ps:

  • I use maven as a build tool. It takes maven ~50 seconds to compile (mvn clean compile), of which 45 seconds are spent running javac (confirmed by running with the -X option).
  • increasing the amount of memory did not help (-Xms500m)
  • I can give more info about my project but it is fairly standard so I'm not sure what information is relevant.

UPDATE

Thanks to Tagir's idea I've managed to find one of the culprits. This class adds 20 seconds to the compilation time:

import org.jooq.DSLContext;
import org.jooq.Field;
import static org.jooq.impl.DSL.field;
import static org.jooq.impl.DSL.round;
import static org.jooq.impl.DSL.sum;


class Test {
  static Object fast(DSLContext sql) {
    Field<Double> a = field("a").cast(Double.class);
    return sql.select()
            .having(round(sum(a).cast(Double.class), 2).ne(0d));
  }
  static Object slow(DSLContext sql) {
    return sql.select()
            .having(round(sum(field("a").cast(Double.class)).cast(Double.class), 2).ne(0d));
  }
}

If the slow method is commented out, the compilation time is back to normal.

like image 248
assylias Avatar asked Jun 08 '15 10:06

assylias


Video Answer


1 Answers

Troubleshooting - general approach

You can start by recreating an empty project and add packages back one by one until the compilation time is affected - that should help you identify the package that is causing the problem.

You can then remove all classes in the package and add them back one by one - that should help you find the classes that cause the issue.

You can then remove all the methods from each of those classes and add them back one by one until you see the compilation time increase (you can save time by only recompiling that one class).

Specific cause

In this case it seems that the root cause is a bug in javac so I have filed a bug report which has been marked as a duplicate of "JEP 215: Tiered Attribution for javac" with a target to be fixed on Java 9.

In the meantime, the workaround is to introduce local variables when there are nested generic method calls that use generic type inference, but unfortunately that does not always work...

like image 90
assylias Avatar answered Sep 20 '22 10:09

assylias