自定义排序算法的性能(与Arrays.sort()和parallelSort()相比)

时间:2018-11-09 12:43:21

标签: java arrays sorting

我用Java实现了一种基本的排序算法,并将其性能与本机方法(Arrays.sort()和Arrays.parallelSort())的性能进行了比较。程序如下。

 public static void main(String[] args) {
    // Randomly populate array
    int[] array = new int[999999];
    for (int i = 0; i < 999999; i++)
        array[i] = (int)Math.ceil(Math.random() * 100);

    long start, end;

    start = System.currentTimeMillis();
    Arrays.sort(array);
    end = System.currentTimeMillis();
    System.out.println("======= Arrays.sort: done in " + (end - start) + " ms ========");

    start = System.currentTimeMillis();
    Arrays.parallelSort(array);
    end = System.currentTimeMillis();
    System.out.println("======= Arrays.parallelSort: done in " + (end - start) + " ms ========");

    start = System.currentTimeMillis();
    orderArray(array);
    end = System.currentTimeMillis();
    System.out.println("======= My way: done in " + (end - start) + " ms ========");
}


private static int[] orderArray(int[] arrayToOrder) {
    for (int i = 1; i < arrayToOrder.length; i++) {
        int currentElementIndex = i;
        while (currentElementIndex > 0 && arrayToOrder[currentElementIndex] < arrayToOrder[currentElementIndex-1]) {
            int temp = arrayToOrder[currentElementIndex];
            arrayToOrder[currentElementIndex] = arrayToOrder[currentElementIndex-1];
            arrayToOrder[currentElementIndex-1] = temp;
            currentElementIndex--;
        }
    }
    return arrayToOrder;
}

当我运行该程序时,我的自定义算法始终比我的机器上的本地查询好几个数量级。这是我得到的代表性输出:

======= Arrays.sort: done in 67 ms ========
======= Arrays.parallelSort: done in 26 ms ========
======= My way: done in 4 ms ========

这独立于:

  • 数组中的元素数(在我的示例中为999999)
  • 执行排序的次数(我在for循环内尝试并重复了很多次)
  • 数据类型(我尝试使用double数组而不是int并没有区别)
  • 我调用每种排序算法的顺序(不影响整体性能的差异)

很显然,我的算法实际上不可能比Java提供的算法更好。我只能想到两种可能的解释:

  • 我衡量绩效的方式存在缺陷
  • 我的算法太简单,缺少一些极端情况

我希望后者是正确的,因为我使用Java来衡量性能的标准方法(使用System.currentTimeMillis())。但是,我已经对算法进行了广泛的测试,到目前为止还没有发现任何谬误-一个int具有预定义的边界(Integer.MIN_VALUE和MAX_VALUE)并且不能为null,我想不出我没有涉及的任何可能的极端情况。

我的算法的时间复杂度(O(n ^ 2))和本机方法的时间复杂度(O(n log(n))))可能显然会造成影响。但是,我再次相信我的复杂性就足够了……

我能不能对此有所了解,所以我知道如何改善算法?

非常感谢,

克里斯。

1 个答案:

答案 0 :(得分:4)

您正在对数组进行排序,但没有在每个路径之间重新打乱数组。这意味着您正在排序最佳情况。在每次调用数组排序方法之间,您可以重新创建数组。

for (int i = 0; i < TEST_SIZE; i++)
    array[i] = (int)Math.ceil(Math.random() * 100);

完成此操作后,您会发现您的算法慢了大约100倍。

也就是说,这并不是首先比较这些方法的最佳方法。至少您应该为每种不同的算法对相同的原始数组进行排序。您还应该对每种算法执行多次迭代,并平均响应。单个试验的结果将是虚假的,并且不能很好地进行比较。