Arrays.sort() 和 Arrays.parallelSort() 之间的区别
Posted
技术标签:
【中文标题】Arrays.sort() 和 Arrays.parallelSort() 之间的区别【英文标题】:Difference between Arrays.sort() and Arrays.parallelSort() 【发布时间】:2013-06-24 01:33:21 【问题描述】:正在查看Java 8
功能,提到了here。无法理解 parallelSort()
究竟做了什么。有人能解释一下sort()
和parallelSort()
之间的实际区别是什么吗?
【问题讨论】:
嗯,parallelSort
使用多线程,而sort
没有...
【参考方案1】:
并行排序使用线程 - 每个线程获取列表的一个块,所有块都并行排序。然后将这些排序的块合并为一个结果。
当集合中有很多元素时,它会更快。并行化的开销(分成块和合并)在较大的集合上变得相当小,但对于较小的集合来说却很大。
看看这张表(当然,结果取决于CPU、内核数、后台进程等):
取自此链接:http://www.javacodegeeks.com/2013/04/arrays-sort-versus-arrays-parallelsort.html
【讨论】:
在谈到开销时,没有“太小”之类的东西。理想情况下,我想要 0。:) 本次测试的时间测量完全不正确。另请注意,如果输入数组小于 4096,则 parallelSort 只是调用顺序排序算法。你真的相信额外的长度检查需要 3 毫秒来检查 602 个元素吗? 嘿@TagirValeev。我知道这个问题很老,但我想我会指出 602 的时间差异不太可能是由长度检查引起的;至少这个检查不是特别责备的。我假设这些时间不是多次测试的平均值,所以也许这是计算机上运行的另一个进程,导致这里出现了 3ms 的差异。只是一些思考的食物。但我同意测量是不正确的,因为只有通过大量的测试用例才能获得准确性。不过,还有其他文章确实显示了类似的性能提升。【参考方案2】: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/Join 任务将负责合并排序的数组。 JDK 8 中的实现使用了这种方法:
将数组分成 4 部分。
将前两部分排序,然后合并。
对接下来的两个部分进行排序,然后将它们合并。 并且对每个部分递归地重复上述步骤,直到要排序的部分的大小不小于上面计算的阈值。
您也可以阅读Javadoc中的实现细节
排序算法是一种并行排序合并,它将数组分解为子数组,这些子数组本身已排序然后合并。当子数组长度达到最小粒度时,使用适当的 Arrays.sort 方法对子数组进行排序。如果指定数组的长度小于最小粒度,则使用适当的 Arrays.sort 方法对其进行排序。该算法需要一个不大于原始数组指定范围大小的工作空间。 ForkJoin 公共池用于执行任何并行任务。
Array.sort():
这使用下面的合并排序或 Tim Sort 来对内容进行排序。这一切都是按顺序完成的,即使归并排序使用分而治之的技术,它也是按顺序完成的。
Source
【讨论】:
【参考方案3】:两种算法的主要区别如下:
1. Arrays.sort() :是顺序排序。
API 使用单线程进行操作。 API 需要更长的时间来执行操作。2。 Arrays.ParallelSort() :是并行排序。
API 使用多个线程。
与 Sort() 相比,API 花费的时间更少。更多的结果,我猜我们都必须等待 JAVA 8 !干杯!!
【讨论】:
【参考方案4】:可以参考the javadoc,说明如果数组足够大,算法使用多个线程:
排序算法是一种并行排序合并,它将数组分解为子数组,这些子数组本身已排序然后合并。当子数组长度达到最小粒度时,使用适当的
Arrays.sort
方法对子数组进行排序。 [...]ForkJoin
公用池用于执行任何并行任务。
【讨论】:
【参考方案5】:简而言之,parallelSort
使用多个线程。如果你真的想知道的话,这个article 有更多的细节。
【讨论】:
【参考方案6】:来自link
Java 集合提供的当前排序实现 框架(Collections.sort 和 Arrays.sort)都执行排序 在调用线程中按顺序操作。此增强功能将 提供与当前提供的相同的排序操作集 Arrays 类,但使用并行实现 分叉/连接框架。这些新的 API 仍然是同步的 到调用线程,因为它不会通过排序 直到并行排序完成。
【讨论】:
【参考方案7】:Array.sort(myArray);
您现在可以使用 -
Arrays.parallelSort(myArray);
这将自动将目标集合分成几个部分,这些部分将在多个核心上独立排序,然后再组合在一起。这里唯一需要注意的是,当在高度多线程的环境中调用时,例如繁忙的 Web 容器,由于增加 CPU 上下文切换的成本,这种方法的好处将开始减少(超过 90%)。
来源-link
【讨论】:
以上是关于Arrays.sort() 和 Arrays.parallelSort() 之间的区别的主要内容,如果未能解决你的问题,请参考以下文章
Arrays.sort() 和 Arrays.parallelSort() 之间的区别
39-java中Arrays.sort 和 collections.sort()总结