[英]Fastest way to sort an array without overwriting it
我想在Java中對int[] array
進行排序,但是將已排序的數組存儲為新數組而不是覆蓋它。
最明顯的方法是創建數組的副本,然后對新數組進行排序,如下所示:
int[] a2 = new int[a.length];
for (int i = 0; i < this.length; i++) {
a2[i] = a[i];
}
Arrays.sort(a2);
但是,有更快的方法嗎? 我們可以在“同時”排序,因為我們將舊數組的元素復制到新數組中嗎?
你可以用
int[] a2 = IntStream.of(a).sorted().toArray();
但我懷疑它比它更快
int[] a2 = a.clone();
Arrays.sort(a2);
無論它的復雜程度如何,因此不要期望超過恆定因子加速。
在迭代舊數組時對新數組進行排序將不會更快。 為此,您可以使用System.arraycopy()而不是創建自己的排序或復制功能。
將指定源數組中的數組從指定位置開始復制到目標數組的指定位置。
例:
int[] a1 = new int[]{1,2,3,4,5}; // I suppose a1...
int[] a2 = new int[a1.length];
System.arraycopy( a1, 0, a2, 0, a1.length );
Arrays.sort(a2);
更新:只要您要求更快的方式對數組進行排序,正如您所看到的那樣,長期討論是否復制它或動態排序將是最佳選擇。 為此你可以嘗試做一些基准測試。 但是如果你使用copy來對它進行排序, 你會發現這里所有都取決於數組的大小和元素 。 。
如果您傾向於使用TreeSet
,則以下代碼TreeSet
目的:
TreeSet<Integer> copied = new TreeSet<>();
for (int i = 0; i < array.length; i++) {
copied.add(i);
}
我試圖測試差異,它實際上取決於數據的大小以及數組中的數據。
但是,我無法評論這種方法的確定性如何,但我肯定會進行一些實驗並在此發布我的發現。
更新:
我使用以下代碼來測試TreeSet
的性能
import java.util.Arrays;
import java.util.Random;
import java.util.TreeSet;
class TestArrayCopy {
public static void main(String[] arg) throws java.io.IOException {
for (int i = 1; i <= 10; i++) {
int arr[] = randomArray();
System.out.println("Array Size: " + arr.length + ". Results for case #" + i);
System.out.println("Using Array Copy:");
copyAndSort(arr);
System.out.println("Using Tree Set:");
useTreeSet(arr);
System.out.println("----------------------------");
}
}
public static void copyAndSort(int array[]) {
long start = System.nanoTime();
for (int j = 0; j < 100; j++) {
int copied[] = Arrays.copyOf(array, array.length);
Arrays.sort(copied);
}
long end = System.nanoTime();
System.out.println(end - start);
}
public static void useTreeSet(int array[]) {
long start = System.nanoTime();
for (int j = 0; j < 100; j++) {
TreeSet<Integer> copied = new TreeSet<>();
for (int i = 0; i < array.length; i++) {
copied.add(i);
}
}
long end = System.nanoTime();
System.out.println(end - start);
}
public static int[] randomArray() {
Random random = new Random();
int len = 100000 + random.nextInt(1000000);
int arr[] = new int[len];
for (int i = 0; i < len; i++) {
arr[i] = random.nextInt(1000000);
}
return arr;
}
}
使用Java 8在Core-i7 64位系統上實現了以下結果:
數組大小:616568。案例#1的結果
使用陣列復制:
7692926921
使用樹集:
16336650396
----------------------------
數組大小:390270。案例#2的結果
使用陣列復制:
4441066232
使用樹集:
9306742954
----------------------------
數組大小:658410。案例#3的結果
使用陣列復制:
8534144532
使用樹集:
17721764026
----------------------------
數組大小:1021396。案例#4的結果
使用陣列復制:
13573512678
使用樹集:
31341152398
----------------------------
數組大小:1034872。案例#5的結果
使用陣列復制:
13298690836
使用樹集:
30950793986
----------------------------
數組大小:466014。案例#6的結果
使用陣列復制:
5501196272
使用樹集:
11704757934
----------------------------
數組大小:190231。案例#7的結果
使用陣列復制:
1662270714
使用樹集:
4465174267
----------------------------
數組大小:681150。案例#8的結果
使用陣列復制:
8262756493
使用樹集:
19079310588
----------------------------
數組大小:627257。案例#9的結果
使用陣列復制:
6725984653
使用樹集:
14468898852
----------------------------
數組大小:397189。案例#10的結果
使用陣列復制:
3122214311
使用樹集:
7356182877
----------------------------
從這些結果可以看出,TreeSet比排序重復數組慢很多。 對我好運動。
int [] a2 = IntStream.of(a).sorted()。toArray();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.