有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java内部语言和内联对Lambda性能的影响?

我使用了这个基准java8-lambda-performance-test,在运行它时,我做了以下工作:

一,。禁用的固有用法

二,。禁用内联

三,。禁用编译 模式

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

这很奇怪,而且在使用和print infrance运行基准测试时,我没有找到对infrance compiledLambdaForm的任何调用

因为数学本质在那里被大量使用,所以。。。我原以为禁用intrinsic会降低性能


共 (2) 个答案

  1. # 1 楼答案

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

    对于数学本质,我认为,由于它们仅用于恒等式方法,而恒等式方法仅用于LambdaExtraAverageLambdaExtraSerial测试,因此它们不会对基准测试结果产生太大影响

  2. # 2 楼答案

    您没有注意到预期性能效果的原因是poorly written benchmark
    我使用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<EmployeeRec> 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倍