调整Java 7以匹配Java 6的性能

cen*_*tic 3 java performance benchmarking java-7

我们有一个简单的单元测试作为我们的性能测试套件的一部分,我们用它来验证基本系统是否合理并在我们开始测试代码之前执行.这样我们通常会验证机器是否适合运行实际的性能测试.

当我们使用此测试比较Java 6和Java 7时,Java 7需要相当长的时间才能执行!我们看到Java 6平均为22秒,Java 7平均为24秒.测试只计算fibonacci,因此在这里只有单个线程中的字节码执行应该与I/O或其他任何东西相关.

目前我们使用带有或不带"-server"的Windows上的默认设置运行它,使用32位和64位JVM,所有运行都表明Java 7的类似降级.

哪些调优选项可能适合尝试将Java 7与Java 6相匹配?

public class BaseLinePerformance {

    @Before
    public void setup() throws Exception{
        fib(46);
    }

    @Test
    public void testBaseLine() throws Exception {
        long start = System.currentTimeMillis();
        fib(46);
        fib(46);
        System.out.println("Time: " + (System.currentTimeMillis() - start));
    }

    public static void fib(final int n) throws Exception {
        for (int i = 0; i < n; i++) {
            System.out.println("fib(" + i + ") = " + fib2(i));
        }
    }

    public static int fib2(final int n) {
        if (n == 0)
            return 0;
        else if (n == 1)
            return 1;
        else
            return fib2(n - 2) + fib2(n - 1);
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:我已经减少了测试以避免睡眠并遵循其他建议如何在Java中编写正确的微基准测试?,我仍然看到Java 7和Java 6之间存在相同的区别,打印编译的额外JVM选项和GC在实际测试期间没有显示任何输出,只打印最初的编译信息.

cen*_*tic 5

我的一位同事在经过多次挖掘后发现了原因:

有一个JVM标志-XX:MaxRecursiveInlineLevel,其默认值为1.在以前的版本中,这个设置的处理似乎略有不正确,所以Sun/Oracle在Java 7中"修复"了这个,但它有副作用有时,内联现在不那么积极地进行,因此递归代码的纯运行时/ CPU时间可能比以前更长.

我们正在测试将其设置为2以获得与Java 6中相同的行为,至少对于相关测试而言.