我已阅读了这篇文章:Java 8 Lambda表达式和匿名内部类的性能差异,其中提供了文章。
在文章中,它说:
在文章中,它说:
我说:“好吧”,并决定编写自己的基准测试,我使用了Lambda调用的行为与匿名类调用完全相同。
jmh
,下面是代码(我还添加了方法引用的基准测试)。public class MyBenchmark {
public static final int TESTS_COUNT = 100_000_000;
@Benchmark
public void testMethod_lambda() {
X x = i -> test(i);
for (long i = 0; i < TESTS_COUNT; i++) {
x.x(i);
}
}
@Benchmark
public void testMethod_methodRefernce() {
X x = this::test;
for (long i = 0; i < TESTS_COUNT; i++) {
x.x(i);
}
}
@Benchmark
public void testMethod_anonymous() {
X x = new X() {
@Override
public void x(Long i) {
test(i);
}
};
for (long i = 0; i < TESTS_COUNT; i++) {
x.x(i);
}
}
interface X {
void x(Long i);
}
public void test(Long i) {
if (i == null) System.out.println("never");
}
}
结果如下(在Intel Core i7 4770k上):
Benchmark Mode Samples Score Score error Units
t.j.MyBenchmark.testMethod_anonymous thrpt 200 16,160 0,044 ops/s
t.j.MyBenchmark.testMethod_lambda thrpt 200 4,102 0,029 ops/s
t.j.MyBenchmark.testMethod_methodRefernce thrpt 200 4,149 0,022 ops/s
如您所见,lambda表达式和匿名方法调用之间存在4倍差距,其中lambda表达式的速度较慢。
问题是:我做错了什么或者对于lambda表达式的性能理论存在误解?
编辑:
# VM invoker: C:\Program Files\Java\jre1.8.0_31\bin\java.exe
# VM options: <none>
# Warmup: 20 iterations, 1 s each
# Measurement: 20 iterations, 1 s each
invokespecial
构造对象,而 lambda 使用invokedynamic
。如果在测试之外构造每个对象的一个实例,我很想看看是否有速度差异。 - resueman