2016-04-15 56 views
1

所以我做了以下的基准,试图了解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 

回答

4

您的代码在基准测试中最老的问题正在下降:您忽略了方法的结果。结果,一切都被扔掉了,你正在测量随机数据。

始终,总是从函数调用中返回值,或者将其与Blackhole.consume一起使用。否则,你不会得到你所期望的东西。

0

TestValueInside和TestValueOutsideLocalCopy是最快为每秒操作是最高的。

这可能是由于在+中使用了一个int。使用可能为空的整数,需要对整型值进行拆箱,因此引发NullPointerException需要额外的检查。

相关问题