【发布时间】:2026-01-07 10:10:02
【问题描述】:
我明天要教一个关于插入排序的演示。一个重要的优化是在内部循环中添加一个检查,一旦你将一个项目放到正确的位置,它就会停止它的迭代。所以基本上,它是从这个开始的:
public static void insertionSort(int[] array) {
for (int i = 0; i < array.length; i++) {
for (int j = i; j > 0; j--) {
if (array[j] < array[j-1]) {
int tmp = array[j];
array[j] = array[j-1];
array[j-1] = tmp;
}
}
}
}
到这里:
public static void insertionSort(int[] array) {
for (int i = 0; i < array.length; i++) {
for (int j = i; j > 0 && array[j] < array[j-1]; j--) {
int tmp = array[j];
array[j] = array[j-1];
array[j-1] = tmp;
}
}
}
第二个版本应该更高效。但是,当我对其进行基准测试时,我实际上是在测量第一个版本的性能更快。我找不到错误。有什么想法吗?
这是我用来进行基准测试的代码:
import java.util.Arrays;
import java.util.Random;
public class InsertionSort {
public static void main(String[] args) {
int[] stuff = getRandomArray(50000);
//System.out.println(Arrays.toString(stuff));
long started = System.currentTimeMillis();
insertionSort(stuff);
long finished = System.currentTimeMillis();
long totalTime = finished - started;
//System.out.println(Arrays.toString(stuff));
System.out.println("Started: " + started);
System.out.println("Finished: " + finished);
System.out.println("Elapsed: " + totalTime);
}
public static int[] getRandomArray(int size) {
int[] array = new int[size];
Random r = new Random();
for (int i = 0; i < array.length; i++) {
array[i] = r.nextInt(size);
}
return array;
}
public static void insertionSort(int[] array) {
// Implementation goes here
}
}
编辑:更改测试数组中的项目数,并注释掉要打印的行
【问题讨论】:
-
您遇到的较慢的幅度是多少?在第二个版本中有一个额外的比较,并且您的数组没有那么长
-
啊,让我编辑一下。我在接近 50000 个项目时注意到它
-
第二个版本大约 1200 毫秒,第一个版本大约 1000 毫秒,非常一致。不是很大,但我希望第一个接近 N^2 计算,而后者更接近 N^2 / 2。第二个算法实际上应该有更少的比较,因为比较在 if 语句中第一个算法被移到第二个 for 循环的条件中。这应该会导致循环更快停止。
-
这很奇怪。使用您提供的代码,我在 OpenJDK 8 上的第一个版本大约 2400 毫秒,第二个版本大约 780 毫秒 ...
-
JVM选项会影响基准测试结果,如果有任何特定选项,您可以分享。
标签: java algorithm sorting insertion-sort