Java 7排序"优化"

Mat*_*ard 25 java optimization jvm

在Java6中,quicksort和mergesort分别用于Arrays#sort原始和对象数组.在Java7中,这些都改变了,DualPivotQuicksort和Timsort.

在新快速排序的来源中,以下评论出现在几个地方(例如第354行):

 /*
  * Here and below we use "a[i] = b; i++;" instead
  * of "a[i++] = b;" due to performance issue.
  */
Run Code Online (Sandbox Code Playgroud)

这是一个性能问题?编译器不会将这些减少到同一个东西吗?

更广泛地说,自己调查这个的好策略是什么?我可以运行基准测试,但我更感兴趣的是分析编译代码中的任何差异.但是,我不知道使用什么工具等.

Mar*_*rau 7

这只是一般问题的答案.

您可以查看字节码并尝试理解差异.也就是说,你可以用自己的方式写一个简单的例子a[i] = b; i++;,a[i++] = b;并看看差异是什么.

显示字节码的最简单方法是javap程序(应该包含在JDK中).编译代码javac SomeFile.java并在代码上运行javap :( javap -c SomeFile-c开关告诉javap输出文件中每个方法的字节码).

如果你正在使用eclipse,你也可以尝试这个.

  • 我不确定如何看待字节码是多么明确.毕竟,大多数优化都发生在JIT中.我会更进一步:在这种情况下字节码完全无关紧要,这个答案是误导性的. (9认同)

tim*_*hew 5

我编写了2个方法test1test2,并将编译后的字节代码的主要部分(Snow Leopard上的Java 1.6)添加为注释:

    /*
     *     14  iload_1 [b]      -> load value from address 1 to sack
     *     15  iastore          -> store value from stack into int array
     *     16  iinc 3 1 [i]     -> int increment value of address 3
     *     19  iinc 3 1 [i]     -> int increment value of address 3
     */
    public void test1() {
        int b = 0;
        int a[] = new int[10];
        for (int i=0; i<10; i++) {
            a[i] = b; 
            i++;
        }
    }

    /*
     *     14  iinc 3 1 [i]     -> increment value of address 3
     *     17  iload_1 [b]      -> load value from address 1 to stack
     *     18  iastore          -> store value from stack into int array
     *     19  iinc 3 1 [i]     -> increment value of address 3 
     */
    public void test2() {
        int b = 0;
        int a[] = new int[10];
        for (int i=0; i<10; i++) {
            a[i++] = b;
        }
    }
Run Code Online (Sandbox Code Playgroud)

操作的顺序inc是不同的.但是test1test2两种方法的操作总和是相等的!所以字节码的性能也应该相同.

  • 可以想象,优化器可以将两个连续的inc调用优化为一个add $ reg,2调用(我认为至少在x86上应该更快?)这对于第二个变体来说要困难得多 - 仍然可行,但可能是热点目前的优化不? (2认同)