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?

csvan
  • 8,782
  • 12
  • 48
  • 91
  • 3
    Why not create simple calculations using Date for each approach? – MGorgon Jun 18 '14 at 20:54
  • 1
    Do you mind expanding on what a "Java 8 closure" is? At least based on [this](https://stackoverflow.com/questions/17204279/does-java-8-support-closures) question such a thing doesn't appear to exist... – awksp Jun 18 '14 at 20:55
  • 1
    @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"](http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html) would probably be more clear in context. – user2864740 Jun 18 '14 at 20:56
  • 3
    You should generally assume Java 8's approach is at least as efficient and possibly more efficient than the anonymous class approach. – Louis Wasserman Jun 18 '14 at 20:57
  • 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. – csvan Jun 18 '14 at 20:58
  • @user2864740 My apologies; I'm not very familiar with functional programming concepts. What you're saying makes sense to me after some googling though. – awksp Jun 18 '14 at 21:01
  • 1
    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. – ajb Jun 18 '14 at 21:07
  • "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. – newacct Jun 20 '14 at 01:40

2 Answers2

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.

user2864740
  • 60,010
  • 15
  • 145
  • 220
dkatzel
  • 31,188
  • 3
  • 63
  • 67
-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)
Arseny
  • 5
  • 1
  • 16
    You're mixing your comparisons. The question was about anonymous classes vs lambdas, but you're comparing for loops and streams. – Coeffect Oct 26 '16 at 21:43