Recently we decided to migrate to Java 8 from Java 7, hence we made some researches and performance tests. We read that there are no objects created for the lambda expressions. ("it seems that it's true") In some articles there is also mentioned that instantiation of lambda expressions can be 100x faster then abstract classes while there is no class loading and instantiation steps, but there are still linkage and capture steps. By the way it's not 100% clear for us what happens in the linkage and capture steps.
By the way we made a comparison between a simple abstract class and lambda expression.
The question for us was whether we can or we should not write lambda expressions in loops.
Abstract class:
Comparator<String> c;
String s1 = "a", s2 = "b";
long time = System.currentTimeMillis();
for (long i = 0; i < it; i++) {
c = new Comparator<String>() {
/**
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
};
c.compare(s1, s2);
}
System.out.println("Anonymous class: " + (System.currentTimeMillis() - time));
Lambda:
Comparator<String> c;
String s1 = "a", s2 = "b";
long time = System.currentTimeMillis();
for (long i = 0; i < it; i++) {
c = (o1, o2) -> o1.compareTo(o2);
c.compare(s1, s2);
}
System.out.println("Anonymous class: " + (System.currentTimeMillis() - time));
In performance perspective there are a lot of classes created for the anonymous classes but there is no memory overhead in case of the lambda expressions.That's fine, but the problem starts with the performance: Anonymous class test: 607ms Lambda test: 1182ms => ~94% slower
It's interesting that the lambda expression variant is much slower than the anonymous one.
Note: just processing the c.compare code takes at around 600ms, which indicates for us that there is no performance overhead for creating a lot of instances of anonymous classes inside the for loop. But the instances are created, it clearly visible if we are looking to the heap of the application when we are processing the anonymous test.
Could somebody explain to us why the lambda version is much slower than the anonymous test version? As we understood the lambda expressions are compiled to static methods inside the original class, but there are also that capture and linkage steps which are not totally clear for us.