为什么System.out :: println比Java 8中的匿名类实现慢?

Amb*_*wal 0 java performance consumer java-8 java-stream

我正在使用一些Java 8 StreamAPI.我很困惑看到以下两个解决方案之间的性能差异,即只打印内容Stream.

解决方案1:

int[] array = new int[] { 0, 1, 2, 3, 4, 5 };
start = System.nanoTime();
Arrays.stream(array).forEach(System.out::println);
System.out.println((System.nanoTime() - start) / 1000000.0f);
Run Code Online (Sandbox Code Playgroud)

解决方案2:

int[] array = new int[] { 0, 1, 2, 3, 4, 5 };
start = System.nanoTime();
Arrays.stream(array).forEach(new IntConsumer() {
    @Override
    public void accept(int value) {
        System.out.println(value);
    }
});
System.out.println((System.nanoTime() - start) / 1000000.0f);
Run Code Online (Sandbox Code Playgroud)

执行时,Solution 1约需要 比时间长5-6倍Solution 2.

系统配置:

  • JRE: 1.8.0_101 64 bit
  • OS: Windows 10 Home 64-bit
  • 内存: 4 GB
  • IDE: Eclipse Mas-1 for Java EE 64-bit

如果有人可以解释,为什么会有这么大的差异会有所帮助?

JMH代码:

public class MyBenchmark {

    @Benchmark
    public void solution_0() {
        int[] array = new int[] { 0, 1, 2, 3, 4, 5 };
        for (int i = 0; i < array.length; i++) {
            System.out.println(array[i]);asdasdas
        }
    }

    @Benchmark
    public void solution_1() {
        int[] array = new int[] { 0, 1, 2, 3, 4, 5 };
        Arrays.stream(array).forEach(new IntConsumer() {
            @Override
            public void accept(int value) {
                System.out.println(value);
            }
        });
    }

    @Benchmark
    public void solution_2() {
        int[] array = new int[] { 0, 1, 2, 3, 4, 5 };
        Arrays.stream(array).forEach(System.out::println);
    }
}
Run Code Online (Sandbox Code Playgroud)

apa*_*gin 9

您正在测量方法引用的实例化,而不是其运行时性能.

在第一次使用方法reference(System.out::println)时,JVM需要创建一个实现IntConsumer接口的内部类.当然,这需要时间.虽然这在应用程序生命周期中只执行一次.

在第二种情况下,你自己做了这样的匿名课程.

如果要测量方法引用的运行时性能,则必须修改基准测试方法.请参阅" 如何在Java中编写正确的微基准测试? "