我们都使用Arrays.sort对对象和原始数组进行排序。 该API在下面使用合并排序或Tim排序对内容进行排序,如下所示:
public static void sort(Object[] a) {if (LegacyMergeSort.userRequested)legacyMergeSort(a);elseComparableTimSort.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);}
}
每个API针对不同大小的双精度值数组所花费的时间如下所示:
列表也有类似的实现,并且列表上的许多操作具有并行的等效项。
翻译自: https://www.javacodegeeks.com/2013/04/arrays-sort-versus-arrays-parallelsort.html