概述
我们都使用过 Arrays.sort() 对对象或原始数据类型数组(byte,short,int,long,char,float,double和boolean)进行排序。在 JDK 8 中,创造者增强了 API 以提供一种新方法:Arrays.parallelSort()。
Arrays.sort()
Arrays.sort() 方法对对象或原始数据类型的数组进行排序。此方法中使用的排序算法是 Dual-Pivot Quicksort。 换句话说,它是快速排序算法的自定义实现,以实现更好的性能。
此方法是单线程的 ,有两种变体:
sort(array)–将整个数组按升序排序
sort(array, fromIndex, toIndex)–仅将从 fromIndex 到 toIndex 的元素排序
优点 | 缺点 |
---|---|
快速处理较小的数据集 | 大型数据集的性能下降 ,没有利用系统的多个核心 |
Arrays.parallelSort
此方法对对象或原始数据类型的数组进行排序。与 sort() 类似,它也有两个变体来对完整数组和部分数组进行排序
parallelSort() 在功能上有所不同。与 sort() 使用单个线程对数据进行顺序排序不同,它使用并行排序-合并排序算法。它将数组分成子数组,这些子数组本身先进行排序然后合并。
为了执行并行任务,它使用 ForkJoin 池。
但是我们需要知道,只有在满足某些条件时,它才会使用并行性。如果数组大小小于或等于 8192,或者处理器只有一个核心,则它将使用顺序的 Dual-Pivot Quicksort 算法。否则,它使用并行排序。
优点 | 缺点 |
---|---|
为大型数据集提供更好的性能 | 对于大小较小的数组,处理速度较慢 |
利用系统的多个核心 |
public class SortTest {
public static void main(String[] args){
for(int i=10;i<Integer.MAX_VALUE;i*=10)
test(i);
}
static void test(long limit){
Random rand = new Random();
IntStream stream = rand.ints(limit);
int[] arr = stream.toArray();
int[] arr1 = Arrays.copyOf(arr, arr.length);
long t1 = System.currentTimeMillis();
Arrays.parallelSort(arr);
long t2 = System.currentTimeMillis();
Arrays.sort(arr1);
long t3 = System.currentTimeMillis();
System.out.println("limit:"+limit+"\t parallelSort: "+(t2-t1)+"ms\tserialSort: "+(t3-t2)+"ms");
}
}
测试结果
//先让数据规模按2的指数幂递增
limit:2 parallelSort: 0ms serialSort: 0ms
limit:4 parallelSort: 0ms serialSort: 0ms
limit:8 parallelSort: 0ms serialSort: 0ms
limit:16 parallelSort: 0ms serialSort: 0ms
limit:32 parallelSort: 0ms serialSort: 0ms
limit:64 parallelSort: 0ms serialSort: 0ms
limit:128 parallelSort: 0ms serialSort: 0ms
limit:256 parallelSort: 0ms serialSort: 0ms
limit:512 parallelSort: 0ms serialSort: 0ms
limit:1024 parallelSort: 0ms serialSort: 0ms
limit:2048 parallelSort: 0ms serialSort: 1ms
limit:4096 parallelSort: 0ms serialSort: 1ms
limit:8192 parallelSort: 1ms serialSort: 1ms
limit:16384 parallelSort: 7ms serialSort: 1ms
limit:32768 parallelSort: 8ms serialSort: 4ms
limit:65536 parallelSort: 16ms serialSort: 8ms
limit:131072 parallelSort: 17ms serialSort: 9ms
limit:262144 parallelSort: 5ms serialSort: 20ms//转折点
limit:524288 parallelSort: 10ms serialSort: 42ms
limit:1048576 parallelSort: 20ms serialSort: 92ms
limit:2097152 parallelSort: 41ms serialSort: 241ms
limit:4194304 parallelSort: 98ms serialSort: 484ms
limit:8388608 parallelSort: 178ms serialSort: 783ms
limit:16777216 parallelSort: 371ms serialSort: 1712ms
limit:33554432 parallelSort: 770ms serialSort: 3470ms
limit:67108864 parallelSort: 1772ms serialSort: 8073ms
//然后按10的指数幂递增
limit:10 parallelSort: 0ms serialSort: 0ms
limit:100 parallelSort: 0ms serialSort: 0ms
limit:1000 parallelSort: 0ms serialSort: 1ms
limit:10000 parallelSort: 5ms serialSort: 1ms
limit:100000 parallelSort: 23ms serialSort: 11ms
limit:1000000 parallelSort: 34ms serialSort: 83ms//转折点
limit:10000000 parallelSort: 216ms serialSort: 1048ms
limit:100000000 parallelSort: 2466ms serialSort: 11992ms
从上面的结果,可以看出当数据规模达到262144(即2的18次方)时,并行排序的性能要超过串行排序。
(该结果受计算机的cpu影响)
结论
在这篇快速文章中,我们看到了 sort() 和 parallelSort() 的不同之处。
根据性能结果,我们可以得出结论,当我们要排序的数据集很大时,parallelSort() 可能是更好的选择。但是,在数组较小的情况下,最好使用 sort(),因为它可以提供更好的性能。