java - 自定义排序算法性能(对比 Arrays.sort() 和 parallelSort())
问题描述
我在 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 循环中尝试并迭代了很多次)
- 数据类型(我尝试使用双精度数组而不是 int 并没有发现任何区别)
- 我调用每个排序算法的顺序(不影响性能的整体差异)
显然,我的算法实际上不可能比 Java 提供的算法更好。我只能想到两种可能的解释:
- 我衡量绩效的方式存在缺陷
- 我的算法太简单了,缺少一些极端情况
我希望后者是正确的,因为我使用了一种相当标准的方式来衡量 Java 的性能(使用 System.currentTimeMillis())。但是,我已经对我的算法进行了广泛的测试,到目前为止还没有发现任何谬误——一个 int 具有预定义的边界(Integer.MIN_VALUE 和 MAX_VALUE)并且不能为空,我想不出我没有涵盖的任何可能的极端情况。
我的算法的时间复杂度 (O(n^2)) 和本机方法的 (O(n log(n)))),这显然会造成影响。然而,我再次相信我的复杂性已经足够了......
我可以从局外人的角度来看待这个问题,这样我就知道如何改进我的算法了?
非常感谢,
克里斯。
解决方案
您正在对数组进行适当的排序,但您没有在每条路径之间重新打乱数组。这意味着您正在对最佳情况进行排序。在每次调用数组排序方法之间,您可以重新创建数组。
for (int i = 0; i < TEST_SIZE; i++)
array[i] = (int)Math.ceil(Math.random() * 100);
完成此操作后,您会注意到您的算法慢了大约 100 倍。
也就是说,这并不是首先比较这些方法的最佳方式。至少你应该为每个不同的算法排序相同的原始数组。您还应该对每个算法执行多次迭代并对响应进行平均。单次试验的结果将是虚假的,作为良好的比较不可靠。
推荐阅读
- c++ - 错误:在执行“R CMD INSTALL”时,“结果”没有命名类型
- windows - JavaFX 将节点/对象拖到 Windows 桌面
- jquery - Jquery点击事件中的水平滚动问题
- permissions - 如何为 Kubernetes 中的共享卷授予完全权限
- java - 在 OpenJDK 中哪里可以找到使用 Launch4j 打包 JavaFX 应用程序所需的 JRE 文件
- ruby-on-rails - 如何使用 RSpec 测试 Sidekiq 工作人员?
- php - PHP调用函数进行输入
- ionic3 - 如何使用 Ionic 3 修复图像滚动缓慢/断断续续的问题?
- python - 当任何表或行更新时,mssql 有什么方法可以通知我的 python 应用程序?
- javascript - JavaScript 正则表达式仅验证 URL 中的路径参数