[英]Why is a block of Java code faster when using synchronized keyword, rather than without using it?
[英]Why is Java faster with a function using an external variable containing X rather than using X directly?
因此,我制定了以下基准测试,以尝试了解Lambas如何影响性能。
@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
您的代码陷入基准测试中最古老的问题:您忽略了方法的结果。 结果,一切都被丢弃了,您正在测量随机数据。
总是,总是,总是从函数调用中返回该值,或通过Blackhole.consume
使用它。 否则,您将无法获得预期的测量结果。
TestValueInside和TestValueOutsideLocalCopy最快,因为每秒的操作最高。
这可能是由于在+
使用了int。 使用可能为null的Integer,需要将其拆箱为int值,并因此引发NullPointerException,需要进行额外的检查。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.