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

我正在使用一些Java 8 Stream API。 我很困惑地看到以下两个解决方案之间的性能差异,即只打印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); 

解决方案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); 

执行时, Solution 1正在执行约。 比Solution 2多5-6倍的时间。

系统配置:

  • JRE: 1.8.0_101 64 bit
  • 操作系统: Windows 10 Home 64-bit
  • RAM: 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); } } 

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

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

在第二种情况下,你自己做了这样一个匿名课程。

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