对慢速编译进行故障排除

时间:2015-06-08 10:58:23

标签: java performance compilation javac

我应该如何调查和解决慢速编译问题

我的项目大约有100个类,编译时间超过45秒,这对我来说似乎很慢。作为参考,我有另外一个项目有50个类,可以在3秒内编译。

PS:

  • 我使用maven作为构建工具。编译需要大约50秒(mvn clean compile),其中45秒用于运行javac(通过使用-X选项运行确认)。
  • 增加内存量没有帮助(-Xms500m
  • 我可以提供有关我的项目的更多信息,但它是相当标准的,所以我不确定哪些信息是相关的。

更新

感谢Tagir的想法,我找到了其中一个罪魁祸首。该类为编译时间增加了20秒:

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));
  }
}

如果注释掉slow方法,编译时间将恢复正常。

3 个答案:

答案 0 :(得分:8)

疑难解答 - 一般方法

您可以先重新创建一个空项目,然后逐个添加包,直到编译时间受到影响 - 这应该可以帮助您识别导致问题的包。

然后,您可以删除包中的所有类并逐个添加它们 - 这可以帮助您找到导致问题的类。

然后,您可以从每个类中删除所有方法并逐个添加,直到您看到编译时间增加(您可以节省only recompiling that one class的时间)。

具体原因

在这种情况下,似乎根本原因是javac中的错误,因此我提交了一个bug report,它已被标记为"JEP 215: Tiered Attribution for javac"的副本,其目标将在Java 9上修复。

与此同时,解决方法是在存在使用泛型类型推断的嵌套泛型方法调用时引入局部变量,但不幸的是,这并不总是有效...

答案 1 :(得分:7)

Java 8的一个鲜为人知的特性是Generalized Target-Type Inference

虽然它允许编写更清晰的代码,但这需要Javac更多的工作。有时,这会导致类型推断问题的指数复杂性。这是一个已知问题,但遗憾的是仍未解决 - 请参阅JDK-8055984JDK-8067767

解决方法是在Java 7兼容级别编译:{{1​​}},或者只是使用更简单的构造。

答案 2 :(得分:1)

有很多与此相关的讨论。添加这些引用以防其他人偶然发现此帖子。

初步讨论:

在我的情况下,我基本上尝试尽可能使用自动生成的代码。或者,您可以尝试Lukas在上面链接的StackOverflow帖子中提到的建议。