为什么排序Long数组比使用Arrays.sort()排序长数组要慢?

时间:2013-12-28 04:57:38

标签: java arrays performance sorting

我得到的结果是,Long array使用Arrays.sort()的排序时间比使用long array排序Arrays.sort()所花费的时间更长。这是代码。

public class ABtest {

public static void main(String[] args) {
    long startTime;
    long endTime;

    //code block 1
    startTime = System.nanoTime();
    Long a[] = new Long[10000];
    for (int i = 0; i < a.length; i++) {
        a[i] = 12l;
    }
    Arrays.sort(a);
    endTime = System.nanoTime();
    System.out.println("code block (has Long array) 1 = " + (endTime - startTime));



    //code block 2
    startTime = System.nanoTime();
    long c[] = new long[10000];
    for (int i = 0; i < c.length; i++) {
        c[i] = 12l;
    }
    Arrays.sort(c);
    endTime = System.nanoTime();
    System.out.println("code block (has long array) 2 = " + (endTime - startTime));

}
}

运行时间:

code block (has Long array) 1 = 3076331

code block (has long array) 2 = 741501

任何人都可以解释这种行为。或者我在这里犯了一些错误?

3 个答案:

答案 0 :(得分:3)

答案与your other benchmarking Question的答案相同。您的基准测试设计得很糟糕,您看到的时序数字无效/有意义。


但是,对Long[]进行排序比对等效long[]进行排序要慢:

  • 这部分是因为比较一对Long值比比较一对long值需要更长的时间。

  • 此外,如果您查看the source code,您会看到使用不同的算法对long[]Object[]进行排序。前者使用Quicksort的形式,后者使用MergeSort或TimSort的形式。

我的理解是算法不同,因为sort算法必须是稳定的;即,如果一对元素相等,则必须保留元素的原始排序。对于原始类型,您可以忽略它,但对于引用类型(例如Long),这会约束可以使用的排序算法。

(基于@ S.Yavari发布的结果,我怀疑算法的差异是更重要的问题。)

答案 1 :(得分:1)

这是我的机器上的代码的结果:

第一轮:

code block (has Long array) 1 = 6070325
code block (has long array) 2 = 8739868

第二轮:

code block (has Long array) 1 = 4449868
code block (has long array) 2 = 6224883

第3次运行:

code block (has Long array) 1 = 5773081
code block (has long array) 2 = 1160343

我认为你的基准设计很糟糕。 如果我们将代码更改为:

import java.util.Arrays;

public class Test {
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            System.out.println("Benchmark " + (i + 1));
            benchmark();
            System.out.println();
        }
    }

    public static void benchmark() {
        long startTime;
        long endTime;

        Long a[] = new Long[10000];
        long b[] = new long[10000];

        for (int i = 0; i < a.length; i++)
            a[i] = 12l;

        for (int i = 0; i < b.length; i++)
            b[i] = 12l;

        //code block 1
        startTime = System.nanoTime();
        Arrays.sort(a);
        endTime = System.nanoTime();
        System.out.println("\tcode block (has Long array) 1 = " + (endTime - startTime));

        //code block 2
        startTime = System.nanoTime();
        Arrays.sort(b);
        endTime = System.nanoTime();
        System.out.println("\tcode block (has long array) 2 = " + (endTime - startTime));
    }
}

我们可以看到你说的结果。这是因为long数据类型和Long对象中的比较方法差异。您知道long是原始数据类型,但Long是一个对象。因此,为了比较两个长值,系统可以比较它们而不使用任何复杂的比较方法,但是为了比较两个Long对象,JVM应该使用Long对象的比较方法,并且该方法需要更多时间。 / p>

请注意,这是第二个代码的结果:

Benchmark 1
code block (has Long array) 1 = 2957778
code block (has long array) 2 = 751911

Benchmark 2
code block (has Long array) 1 = 2081759
code block (has long array) 2 = 392857

Benchmark 3
code block (has Long array) 1 = 2031473
code block (has long array) 2 = 410946

Benchmark 4
code block (has Long array) 1 = 2016387
code block (has long array) 2 = 360241

Benchmark 5
code block (has Long array) 1 = 2070235
code block (has long array) 2 = 360870

Benchmark 6
code block (has Long array) 1 = 2105156
code block (has long array) 2 = 360801

Benchmark 7
code block (has Long array) 1 = 2020928
code block (has long array) 2 = 386013

Benchmark 8
code block (has Long array) 1 = 1976229
code block (has long array) 2 = 359682

Benchmark 9
code block (has Long array) 1 = 5213093
code block (has long array) 2 = 363664

Benchmark 10
code block (has Long array) 1 = 3999880
code block (has long array) 2 = 361638

答案 2 :(得分:1)

可以比较长值,同时在比较之前需要提取盒装值Long(只是预感)。

但是您的测试存在问题。您将包括分配阵列并填充它的时间。您没有给JVM足够的时间来计算调优的热点,也可能会遇到垃圾收集时间。

您还可以使用更好的测试数据。已经按升序或降序排序的数组的时序是否有差异?当阵列更随机时,它们如何公平?

相关问题