web-dev-qa-db-ja.com

遅いコンパイルのトラブルシューティング

コンパイルが遅い問題を調査してトラブルシューティングするにはどうすればよいですか

私のプロジェクトには約100のクラスがあり、コンパイルに45秒以上かかりますが、これは私には非常に遅いようです。参考までに、3秒でコンパイルされる50クラスの別のプロジェクトがあります。

ps:

  • 私はビルドツールとしてMavenを使用しています。 Mavenのコンパイルには約50秒かかり(mvn clean compile)、そのうち45秒がjavacの実行に費やされます(-Xオプションで実行することで確認できます)。
  • メモリの量を増やしても役に立ちませんでした(-Xms500m
  • 私は自分のプロジェクトについてもっと情報を与えることができますが、それはかなり標準的であるため、どの情報が関連しているかわかりません。

更新

Tagirのアイデアのおかげで、私は何とか犯人の1人を見つけることができました。このクラスは、コンパイル時間に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メソッドがコメントアウトされている場合、コンパイル時間は通常に戻ります。

19
assylias

トラブルシューティング-一般的なアプローチ

空のプロジェクトを再作成することから始めて、コンパイル時間が影響を受けるまでパッケージを1つずつ追加し直すことができます。これは、問題の原因となっているパッケージを特定するのに役立ちます。

次に、パッケージ内のすべてのクラスを削除して、それらを1つずつ追加し直すことができます。これは、問題の原因となっているクラスを見つけるのに役立ちます。

次に、これらの各クラスからすべてのメソッドを削除し、コンパイル時間が長くなるまで1つずつ追加し直します( その1つのクラスを再コンパイルするだけで時間を節約できます )。

特定の原因

この場合、根本的な原因はjavacのバグであると思われるため、 「JEP215:javacの階層型属性」 の重複としてマークされた バグレポート を提出しました。 Java 9で修正されます。

当面の間、回避策は、ジェネリック型推論を使用するネストされたジェネリックメソッド呼び出しがある場合にローカル変数を導入することですが、残念ながら、それが常に機能するとは限りません...

8
assylias

Java 8のあまり知られていない機能の1つは、 一般化されたターゲット型推論 です。

より明確なコードを書くことはできますが、これにはJavacの作業がさらに必要になります。これにより、型推論の問題が指数関数的に複雑になる場合があります。これは既知の問題ですが、残念ながらまだ解決されていません JDK-8055984JDK-8067767 を参照してください。

回避策は、Java 7-互換性レベル:javac -source 7でコンパイルするか、より単純な構造を使用することです。

7
apangin

これに関連して複数の議論がありました。他の誰かがこの投稿に遭遇した場合に備えて、これらの参照を追加します。

最初の議論:

私の場合、基本的には自動生成されたコードを可能な限り使用しようとしました。または、上記のリンク先のStackOverflowの投稿でLukasが言及している提案を試すこともできます。

1
csgeek