我已经使用了这个基准测试java8-lambda-performance-test,在运行它时我做了以下几点:
1.Disabled内在用法
2.Disabled Inlining
3.Disabled编译模式
我发现禁用两个第一次优化对结果没有影响.
这很奇怪,而且当运行基准和打印内在时,我没有找到任何对内在的调用 compiledLambdaForm
由于数学内在函数大量使用_min,_pow ...我期待禁用内在函数会降低性能
您没有注意到预期的性能影响的原因是基准测试编写得不好。\n我使用JMH
重写了基准测试,事情终于变得正确了。
package lambdademo;\n\nimport org.openjdk.jmh.annotations.*;\n\nimport java.util.List;\n\n@State(Scope.Benchmark)\npublic class LambdaBenchmark {\n @Param("100")\n private static int loopCount;\n\n private static double identity(double val) {\n double result = 0;\n for (int i=0; i < loopCount; i++) {\n result += Math.sqrt(Math.abs(Math.pow(val, 2))); \n }\n return result / loopCount;\n }\n\n private List<EmployeeRec> employeeList = new EmployeeFile().loadEmployeeList();\n\n @Benchmark\n public double streamAverage() {\n return streamAverageNoInline();\n }\n\n @Benchmark\n @Fork(jvmArgs = "-XX:-Inline")\n public double streamAverageNoInline() {\n return employeeList.stream()\n .filter(s -> s.getGender().equals("M"))\n .mapToDouble(s -> s.getAge())\n .average()\n .getAsDouble();\n }\n\n @Benchmark\n public double streamMath() {\n return streamMathNoIntrinsic();\n }\n\n @Benchmark\n @Fork(jvmArgs = {"-XX:+UnlockDiagnosticVMOptions", "-XX:DisableIntrinsic=_dpow,_dabs,_dsqrt"})\n public double streamMathNoIntrinsic() {\n return employeeList.stream()\n .filter(s -> s.getGender().equals("M"))\n .mapToDouble(s -> identity(s.getAge()))\n .average()\n .getAsDouble();\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n结果如下:
\n\nBenchmark Mode Cnt Score Error Units\nLambdaBenchmark.streamAverage avgt 5 71,490 \xc2\xb1 0,770 ms/op\nLambdaBenchmark.streamAverageNoInline avgt 5 122,740 \xc2\xb1 0,576 ms/op\nLambdaBenchmark.streamMath avgt 5 92,672 \xc2\xb1 1,538 ms/op\nLambdaBenchmark.streamMathNoIntrinsic avgt 5 5747,007 \xc2\xb1 20,387 ms/op\nRun Code Online (Sandbox Code Playgroud)\n\n正如预期的那样,基准测试的-XX:-Inline工作时间延长了 70%,而禁用数学内在函数的版本似乎慢了 60 倍!
| 归档时间: |
|
| 查看次数: |
285 次 |
| 最近记录: |