对慢速编译进行故障排除
我应该怎么做才能调查和解决慢速编译问题 ?
我的项目有大约100个类,编译时间超过45秒,这对我来说似乎很慢。 作为参考,我有另外一个项目有50个类,在3秒内编译。
PS:
- 我使用maven作为构建工具。 编译需要大约50秒(
mvn clean compile
),其中45秒用于运行javac(通过使用-X
选项运行确认)。 - 增加内存量没有帮助(
-Xms500m
) - 我可以提供有关我的项目的更多信息,但它是相当标准的,所以我不确定哪些信息是相关的。
UPDATE
感谢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 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
方法被注释掉,则编译时间恢复正常。
故障排除 – 一般方法
您可以首先重新创建一个空项目并逐个添加包,直到编译时间受到影响 – 这应该可以帮助您识别导致问题的包。
然后,您可以删除包中的所有类并逐个添加它们 – 这应该可以帮助您找到导致问题的类。
然后,您可以从每个类中删除所有方法并逐个添加它们,直到您看到编译时间增加(您可以通过仅重新编译该类来节省时间)。
具体原因
在这种情况下,似乎根本原因是javac中的错误,所以我已经提交了一个错误报告 ,该报告已被标记为“JEP 215:javac的分层归因”的副本,其目标将在Java 9上修复。
与此同时,解决方法是在存在使用generics类型推断的嵌套generics方法调用时引入局部变量,但不幸的是,这并不总是有效…
Java 8的一个不太知名的特征是广义目标类型推断 。
虽然它允许编写更清晰的代码,但这需要Javac
更多工作。 有时,这会导致类型推断问题的指数复杂性。 这是一个已知问题,但遗憾的是仍未解决 – 请参阅JDK-8055984 , JDK-8067767 。
解决方法是在Java 7兼容级别编译: javac -source 7
,或者只是使用更简单的构造。
有很多与此相关的讨论。 添加这些参考,以防其他人偶然发现这篇文章。
初步讨论:
- https://groups.google.com/forum/#!topic/jooq-user/grv6Wu_sFtA
- 使用jOOQ 3.6 +,纯SQL和javac编译器进行慢速编译
在我的情况下,我基本上尝试尽可能使用自动生成的代码。 或者,您可以尝试Lukas在上面链接的StackOverflowpost中提到的建议。