首页 > 解决方案 > 是否可以并行编译大型 Java 模块?

问题描述

我知道可以使用多个线程编译多个模块,其中每个线程编译一个模块,但是如果我有一个大模块怎么办?Javac 或 Eclipse Java 编译器是否支持并行编译单个模块(使用多个线程)?还是有其他支持它的Java编译器?

更新:我创建了一个 Java 源文件,其中包含约 50k 简单方法(仅用于本测试),例如:

    static int add1(int a, int b, int c) {
        return 2 * a + 55 * b - c;
    }

   static int add2(int a, int b, int c) {
        return 2 * a + 55 * b - c;
    }

   static int add3(int a, int b, int c) {
        return 2 * a + 55 * b - c;
    }

这些方法不相互依赖,因此编译可以并行完成(至少在理论上)。在我的 12 核 + HT 机器上编译这个文件Javac会导致平均 20% 的 CPU 使用率和高达 50% 的非常短的峰值。这使我相信,虽然内部进行了一些并行化Javac,但它确实很小。

有趣的是,如果我使用相同数量的方法创建 2、3 或 4 个类,并使用单个进程同时编译它们Javac,我无法获得更高的 CPU 使用率。编译花费的时间正好是 2x、3x、4x,这表明 Javac 不会并行编译这些完全不相关的类。但是如果我启动单独的 Javac 进程来分别编译这些文件,当使用 4 个文件(= 进程)时,CPU 会跳到几乎 100% Javac,编译时间仅比编译单个文件高 5-10%(与此相比,一个Javac进程编译所有这 4 个文件,编译时间要长 400%)。

所以我的观点是Javac确实使用多线程编译文件,但它仅限于〜4个线程,它不能充分利用12核机器。在我看来,它似乎是串行Javac编译多个文件,它只使用内核/线程来并行编译一个文件(我相信当一个文件被编译时,某些部分可以并行完成,这就是 Javac 所做的,但是并行编译多个文件呢?如果我有 100 个独立的文件,我应该能够看到我的 CPU 跳到 100%,但事实并非如此。)

标签: javaperformancecompilationjavac

解决方案


是的,可以并行构建 Java 代码。

Java 编译器 ( javac) 本身不这样做,但 Maven 和 Ant(以及某些版本的 Make)都可以javac并行运行多个实例。

此外,Eclipse Java 编译器是多线程的,您可以告诉 Maven 使用它而不是javac; 见https://stackoverflow.com/a/372​​7542/139985


我注意到您的示例涉及使用大量方法编译单个类。并行编译器实例对此无济于事。Eclipse 编译器可能会有所帮助,具体取决于它的实现方式。

但是,我告诉你,这是一个不切实际的例子。人们不会在现实生活中编写那样的代码1,并且可以(并且应该)编写代码生成器以不发出那样的源代码。

1 - 他们的同事会反抗......


推荐阅读