Performance difference between Java 8 lambdas and anonymous inner classes
Asked Answered
E

2

58

Before Java 8, lambda functionality could be achieved by using anonymous inner classes. For example:

interface Lambda {
    void doStuff();
}

// ...

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

// ...

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

In terms of performance, is there a difference between still using this approach and using the new Java 8 lambdas?

Estivation answered 18/6, 2014 at 20:52 Comment(8)
Why not create simple calculations using Date for each approach?Middy
Do you mind expanding on what a "Java 8 closure" is? At least based on this question such a thing doesn't appear to exist...Tirpitz
@user3580294 Arguably, even anonymous inner classes create closures, albeit to an immutable binding (variable) context. Would one argue Haskell doesn't have closures due to immutability of bindings..? But, in any case "Lambda Expressions" would probably be more clear in context.Micronucleus
You should generally assume Java 8's approach is at least as efficient and possibly more efficient than the anonymous class approach.Butchery
I might have the definitions wrong, will look into that. The question remains the same however, in the sense that I am asking about essentially equivalent ways to implement callbacks.Estivation
@Micronucleus My apologies; I'm not very familiar with functional programming concepts. What you're saying makes sense to me after some googling though.Tirpitz
From what I can tell (JLS 15.27.4), a lambda's execution may result in creating a new object of a class that implements a functional interface (same as the anonymous inner class example?), but it could result in an existing object if it doesn't need to create a new one. The JLS isn't clear on which. If it's the latter, the result could be a performance improvement.Pointsman
"Before Java 8, lambda functionality could, to an extent, be achieved by using anonymous inner classes. " It could, to every extent be achieved with anonymous classes.Pants
G
90

Oracle has posted a study comparing performance between Lambdas and anonymous classes

See JDK 8: Lambda Performance Study by Sergey Kuksenko, which is 74 slides long.

Summary: slow to warm up but when JIT inlines it worst case just as fast as anonymous class but can be faster.

Goofball answered 18/6, 2014 at 21:0 Comment(2)
Seems to be slides, not pages. Good find.Estivation
@Micronucleus added 1 sentence summary, sorry took a while to read all the slidesGoofball
B
-7

As I found, the iterating over array with Stream is working much slower (74 slides are not consider such the case). I think that it is not the only performance leaks in lambdas (guess, it will be improved in the future). The example below was running with Java 8 without any options:

    //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)
Beetner answered 26/10, 2016 at 9:47 Comment(1)
You're mixing your comparisons. The question was about anonymous classes vs lambdas, but you're comparing for loops and streams.Orpington

© 2022 - 2024 — McMap. All rights reserved.