为什么System.out :: println比Java 8中的匿名类实现慢? [英] Why System.out::println is slower than anonymous class implementation in Java 8?

查看:226
本文介绍了为什么System.out :: println比Java 8中的匿名类实现慢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I was working with some Java 8 Stream APIs. I am confused to see the performance difference between below two solutions, that are just printing the contents of 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);

执行时,解决方案1 ​​正在接受约。时间比解决方案2 多5-6倍。

For execution, Solution 1 is taking approx. 5-6 times more time than Solution 2.

系统配置


  • JRE: 1.8.0_101 64位

  • 操作系统: Windows 10 Home 64位

  • RAM: 4 GB

  • IDE: Eclipse Mas-1 for Java EE 64位

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

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

It would be helpful if someone can explain, Why there is this huge difference?

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);
    }
}


推荐答案

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

You are measuring the instantiation of method reference, not its runtime performance.

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

On the first use of method reference (System.out::println) JVM needs to create an internal class which implements IntConsumer interface. Of course, this takes time. Though this is done only once during application lifetime.

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

In the second case you've made such anonymous class yourself.

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

If you wish to measure the runtime performance of method references, you have to revise the benchmarking metodology. See "How do I write a correct micro-benchmark in Java?"

这篇关于为什么System.out :: println比Java 8中的匿名类实现慢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆