我们都使用Arrays.sort对对象和原始数组进行排序。 该API在下面使用合并排序或Tim排序对内容进行排序,如下所示:
public static void sort(Object[] a) {
if (LegacyMergeSort.userRequested)
legacyMergeSort(a);
else
ComparableTimSort.sort(a);
}
即使合并排序使用分而治之技术,所有这些操作都是顺序执行的。 Java 8来了,引入了一个新的API Arrays#parallelSort用于排序。 这是并行进行的排序。 有趣的权利! 让我们看看它是如何做的...
Arrays#parallelSort使用Java 7中引入的Fork / Join框架将排序任务分配给线程池中可用的多个线程。 这被称为吃自己的狗粮 。 Fork / Join实现了一种工作窃取算法,该算法在空闲线程中可以窃取在另一个线程中排队的任务。
Arrays#parallelSort的概述:
该方法使用阈值,并且使用Arrays#sort()API对小于该阈值的任何大小的数组进行排序(即顺序排序)。 并根据机器的并行性,数组大小计算阈值,并计算为:
private static final int getSplitThreshold(int n) {
int p = ForkJoinPool.getCommonPoolParallelism();
int t = (p > 1) ? (1 + n / (p << 3)) : n;
return t < MIN_ARRAY_SORT_GRAN ? MIN_ARRAY_SORT_GRAN : t;
}
一旦决定是对数组进行并行还是串行排序,现在就决定如何将数组分为多个部分,然后将每个部分分配给一个Fork / Join任务,该任务将负责对它进行排序,然后再进行另一个Fork /连接任务,将合并合并的数组。 JDK 8中的实现使用以下方法:
–将阵列分为4部分。
–排序前两个部分,然后将它们合并。 –对接下来的两个部分进行排序,然后将它们合并。 并且对每个零件递归地重复上述步骤,直到要分类的零件的尺寸不小于上面计算的阈值。
一些有趣的结果:
我试图比较Arrays#sort和Arrays#parallelSort在具有4个CPU的计算机上花费的时间。 我用于此比较的程序是:
public class ArraysParallelDemo {
public static void main(String[] args) throws FileNotFoundException {
List<Double> arraySource = new ArrayList<>();
Scanner reader = new Scanner(ClassLoader.
getSystemResourceAsStream("java8demo/large_array_input"));
while(reader.hasNext()){
String line = reader.nextLine();
String[] strNums = line.split(",");
for ( String strN : strNums){
arraySource.add(Double.parseDouble(strN));
}
}
System.out.println(arraySource.size());
Double [] myArray = new Double[1];
myArray = arraySource.toArray(myArray);
long startTime = System.currentTimeMillis();
Arrays.sort(myArray);
long endTime = System.currentTimeMillis();
System.out.println("Time take in serial: "+
(endTime-startTime)/1000.0);
Double [] myArray2 = new Double[1];
myArray2 = arraySource.toArray(myArray);
startTime = System.currentTimeMillis();
Arrays.parallelSort(myArray2);
endTime = System.currentTimeMillis();
System.out.println("Time take in parallel: "+
(endTime-startTime)/1000.0);
}
}
列表也有类似的实现,并且列表上的许多操作具有并行的等效项。
翻译自: https://www.javacodegeeks.com/2013/04/arrays-sort-versus-arrays-parallelsort.html