为什么Java使用包含X的外部变量的函数比直接使用X更快?
因此,我制定了以下基准测试,试图了解Lambas是如何影响性能的为什么Java使用包含X的外部变量的函数比直接使用X更快?,java,performance,lambda,jmh,Java,Performance,Lambda,Jmh,因此,我制定了以下基准测试,试图了解Lambas是如何影响性能的 @Fork(1) @Measurement(iterations = 5) @Warmup(iterations = 5) public class LambdaBenchmark { @State(Scope.Thread) public static class MyInteger { public Integer value = 10; } @Benchmark p
@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);
}
}
为什么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
TestValueInside和TestValueOutsideLocalCopy速度最快,因为每秒的操作数最高
这可能是因为在
+
中使用了int。使用可能为null的整数,需要取消装箱为int值,因此引发NullPointerException需要额外检查。TestValueInside和TestValueOutsideLocalCopy最快,因为每秒的操作数最高
这可能是因为在
+
中使用了int。使用可能为null的整数,需要取消装箱为int值,因此引发NullPointerException需要额外检查。您的代码陷入了基准测试中最古老的问题:您忽略了方法的结果。结果,所有的东西都被扔掉了,你在测量随机数据
总是,总是,总是从函数调用返回值,或者让它与
Blackhole.consume一起使用。否则,您将无法获得预期的测量结果。您的代码陷入了基准测试中最古老的问题:您忽略了方法的结果。结果,所有的东西都被扔掉了,你在测量随机数据
总是,总是,总是从函数调用返回值,或者让它与Blackhole.consume一起使用。否则,您将无法获得预期的测量结果
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