所以我做了以下的基准,试图了解Lambas如何影响性能。为什么Java使用包含X的外部变量而不是直接使用X的函数更快?
@Fork(1)
@Measurement(iterations = 5)
@Warmup(iterations = 5)
public class LambdaBenchmark {
@State(Scope.Thread)
public static class MyInteger {
public Integer value = 10;
}
@Benchmark
public void TestValueInside(MyInteger integer) {
Function<Integer, Integer> toTest = i -> i + 10;
toTest.apply(1);
}
@Benchmark
public void TestValueOutside(MyInteger integer) {
Function<Integer, Integer> toTest = i -> i + integer.value;
toTest.apply(1);
}
@Benchmark
public void TestValueOutsideFinal(MyInteger integer) {
int i2 = 10;
Function<Integer, Integer> toTest = i -> i + i2;
toTest.apply(1);
}
@Benchmark
public void TestValueOutsideLocalCopy(MyInteger integer) {
int i2 = integer.value;
Function<Integer, Integer> toTest = i -> i + i2;
toTest.apply(1);
}
}
我有点对结果感到困惑:
Benchmark Mode Cnt Score Error Units
LambdaBenchmark.TestValueInside thrpt 5 1494683335,686 ▒ 157769032,327 ops/s
LambdaBenchmark.TestValueOutside thrpt 5 755197977,631 ▒ 39587849,696 ops/s
LambdaBenchmark.TestValueOutsideFinal thrpt 5 3007751583,191 ▒ 178696557,885 ops/s
LambdaBenchmark.TestValueOutsideLocalCopy thrpt 5 771307179,267 ▒ 13613431,113 ops/s
为什么TestValueOutsideFinal
这么多比TestValueInside
快?我们正在使用一个可能被认为是最终的外部变量,但它仍然是一个变量而不是一个直接值?或者值10
不断被重新创建,而不是始终使用相同的地址变量?
编辑:
考虑什么@AlBlue后说,它确实显示更接近的结果。
下面是结果,一旦我把每个值:
Benchmark Mode Cnt Score Error Units
LambdaBenchmark.TestValueInside thrpt 5 309129197,389 ▒ 32089680,994 ops/s
LambdaBenchmark.TestValueOutside thrpt 5 283435336,319 ▒ 52230809,938 ops/s
LambdaBenchmark.TestValueOutsideFinal thrpt 5 360590518,854 ▒ 3072257,599 ops/s
LambdaBenchmark.TestValueOutsideLocalCopy thrpt 5 279159794,477 ▒ 12871790,409 ops/s