Java8Lambdas和匿名内部类之间的性能差异

Java8Lambdas和匿名内部类之间的性能差异,java,performance,closures,java-8,Java,Performance,Closures,Java 8,在Java8之前,lambda功能可以通过使用匿名内部类来实现。例如: interface Lambda { void doStuff(); } // ... public void doWithCallback(Lambda callback) { // ... callback.doStuff(); } // ... doWithCallback(new Lambda { public void doStuff() { // ...

在Java8之前,lambda功能可以通过使用匿名内部类来实现。例如:

interface Lambda {
    void doStuff();
}

// ...

public void doWithCallback(Lambda callback) {
    // ...
    callback.doStuff();
}

// ...

doWithCallback(new Lambda { 
    public void doStuff() { 
        // ... 
    } 
});

在性能方面,仍然使用这种方法和使用新的Java8Lambdas之间有什么区别吗?

Oracle发布了一项研究,比较了lambdas和匿名类之间的性能

参见Sergey Kuksenko,长74张幻灯片


摘要:慢速预热,但JIT在最坏的情况下和匿名类一样快,但可以更快。

我发现,用流进行重复数组的工作要慢得多(74张幻灯片不考虑这样的情况)。我认为这并不是lambdas中唯一的性能漏洞(我猜,它在将来会得到改进)。下面的示例使用Java 8运行,没有任何选项:

    //Language is an enum 
    Language[] array = Language.values();
    System.err.println(array.length); // 72 items
    long t = System.nanoTime();
    for (Language l : array) System.out.println(l.getLanguageName());
    System.err.println(System.nanoTime()-t); //nano time  1864724

    t = System.nanoTime();
    Arrays.stream(array).forEach(v -> System.out.println(v.getLanguageName()));
    System.err.println(System.nanoTime()-t); //nano time 55812625 (55812625/1864724 = 29.93 times longer)

    List<Language> list = Arrays.asList(array);

    t = System.nanoTime();
    for (Language l : list) System.out.println(l.getLanguageName());
    System.err.println(System.nanoTime()-t); //nano time 1435008

    t = System.nanoTime();
    list.forEach(v -> System.out.println(v.getLanguageName()));
    System.err.println(System.nanoTime()-t); //nano time 1619973 (1619973/1435008 = 1.128 times longer)
//语言是一个枚举
Language[]数组=Language.values();
System.err.println(array.length);//72项
long t=System.nanoTime();
for(语言l:array)System.out.println(l.getLanguageName());
System.err.println(System.nanoTime()-t)//纳米时间1864724
t=System.nanoTime();
Arrays.stream(array.forEach)(v->System.out.println(v.getLanguageName());
System.err.println(System.nanoTime()-t)//纳米时间55812625(55812625/1864724=29.93倍)
列表=数组。asList(数组);
t=System.nanoTime();
for(语言l:list)System.out.println(l.getLanguageName());
System.err.println(System.nanoTime()-t)//纳米时间143508
t=System.nanoTime();
list.forEach(v->System.out.println(v.getLanguageName());
System.err.println(System.nanoTime()-t)//纳米时间1619973(1619973/143508=1.128倍)

为什么不为每种方法创建使用日期的简单计算?您介意扩展“Java 8闭包”是什么吗?至少基于这样一个问题,这种东西似乎不存在…@user3580294可以说,即使是匿名内部类也会创建闭包,尽管是在不可变的绑定(变量)上下文中。有人会说Haskell由于绑定的不变性而没有闭包吗。。?但是,在任何情况下,在上下文中都可能更清楚。您通常应该假设Java 8的方法至少与匿名类方法一样有效,并且可能比匿名类方法更有效。据我所知(JLS 15.27.4),lambda的执行可能会导致创建实现函数接口的类的新对象(与匿名内部类示例相同?),但如果不需要创建新对象,则可能会产生现有对象。JLS不清楚是在哪个对象上。如果是后者,则可能会提高性能。似乎是幻灯片,而不是页面。发现得不错。@user2864740添加了一句话摘要,抱歉,花了一段时间阅读了所有幻灯片。您正在混合比较。问题w关于匿名类和lambdas,但是您正在比较循环和流。