繁体   English   中英

为什么Java使用带有包含X的外部变量的函数而不是直接使用X的函数更快?

[英]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

为什么TestValueOutsideFinalTestValueInside快得多? 我们使用的外部变量可能被认为是最终变量,但它仍然是变量而不是直接值? 还是不断地重新创建值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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM