我做了两个快速排序的实现:顺序和并行.第二个是使用ForkJoinPool编写的,使用了4个线程(我在下面添加了实现) 排序函数与ArrayList配合使用:
override fun sort(array: ArrayList<Int>): ArrayList<Int> {
...
}
我在大小为1e3-1e7的数组上对它们进行了测试,对于所有大小的数组,并行实现的速度大约是顺序实现的2.5倍.但是starting from the size=1e8 parallel algorithm works about 2 times slower,然后是连续的一次.
class ParQuickSort(
private val seqBlockSize:Int = 1000,
nThreads: Int = 4
) : QuickSort {
private val threadPool = ForkJoinPool(nThreads)
override fun sort(array: IntArray): IntArray {
threadPool.invoke(
SortTask(array, 0, array.size - 1, seqBlockSize)
)
return array
}
fun shutdown() {
threadPool.shutdownNow()
}
private class SortTask(
val array: IntArray,
val l: Int,
val r: Int,
val seqBlockSize: Int
) : RecursiveTask<Unit>() {
private val rand = Random()
private val seqSort = SeqQuickSort()
override fun compute() {
if (l < r) {
if (r - l <= seqBlockSize) {
seqSort.quickSortInterval(array, l, r)
return
}
val m = partition(array, l, r)
invokeAll(
SortTask(array, l, m, seqBlockSize),
SortTask(array, m + 1, r, seqBlockSize)
)
}
}
private fun partition(array: IntArray, l: Int, r: Int): Int {
...
}
private fun swap(array: IntArray, first: Int, second: Int) {
...
}
}
}
当我更改ArrayList to IntArray时,并行实现显示了1e8数组大小的更好结果(对于较小的数组,其速度大约是顺序的2.5倍).
我知道ArrayList的很多缺点-自动装箱,取消装箱等,IntArray等价于int[],所以它可以处理原语.但是为什么使用ArrayList的并行实现开始只对大量元素(1 e8)给出糟糕的性能?