内在函数和内联对Lambda性能的影响?

我已经使用了这个基准测试java8-lambda-performance-test ,在运行它时我做了以下几点:

1.Disabled内在用法

2.Disabled Inlining

3.Disabled编译模式

我发现禁用两个第一次优化对结果没有影响。

这很奇怪,而且当运行基准测试和打印内在时,我没有找到任何调用内在的compiledLambdaForm

由于数学内在函数大量使用_min,_pow …我期待禁用内在函数会降低性能

您没有注意到预期的性能影响的原因是基准编写不佳 。
我用JMH重新编写了基准测试,事情终于正确了。

 package lambdademo; import org.openjdk.jmh.annotations.*; import java.util.List; @State(Scope.Benchmark) public class LambdaBenchmark { @Param("100") private static int loopCount; private static double identity(double val) { double result = 0; for (int i=0; i < loopCount; i++) { result += Math.sqrt(Math.abs(Math.pow(val, 2))); } return result / loopCount; } private List employeeList = new EmployeeFile().loadEmployeeList(); @Benchmark public double streamAverage() { return streamAverageNoInline(); } @Benchmark @Fork(jvmArgs = "-XX:-Inline") public double streamAverageNoInline() { return employeeList.stream() .filter(s -> s.getGender().equals("M")) .mapToDouble(s -> s.getAge()) .average() .getAsDouble(); } @Benchmark public double streamMath() { return streamMathNoIntrinsic(); } @Benchmark @Fork(jvmArgs = {"-XX:+UnlockDiagnosticVMOptions", "-XX:DisableIntrinsic=_dpow,_dabs,_dsqrt"}) public double streamMathNoIntrinsic() { return employeeList.stream() .filter(s -> s.getGender().equals("M")) .mapToDouble(s -> identity(s.getAge())) .average() .getAsDouble(); } } 

结果如下:

 Benchmark Mode Cnt Score Error Units LambdaBenchmark.streamAverage avgt 5 71,490 ± 0,770 ms/op LambdaBenchmark.streamAverageNoInline avgt 5 122,740 ± 0,576 ms/op LambdaBenchmark.streamMath avgt 5 92,672 ± 1,538 ms/op LambdaBenchmark.streamMathNoIntrinsic avgt 5 5747,007 ± 20,387 ms/op 

正如预期的那样,使用-XX:-Inline的基准测试的工作时间延长了70%,而禁用数学内在函数的版本显示速度慢了60倍!

我认为内在函数没有任何影响,因为Lambda表达式主要使用LambdaMetaFactory.LambdaMetaFactory. 这就是为什么内联和内在函数对lambda本身没有影响的原因。

现在对于数学内在函数,我相信,因为它们仅用于身份方法,它仅用于LambdaExtraAverageLambdaExtraSerial测试,因此它们不会影响基准测试结果。