【发布时间】:2016-02-10 01:20:34
【问题描述】:
我正在根据自定义排序对整数索引进行排序。我发现这里使用的 Ordering[T] 使排序比使用直接调用 compare 方法的手工快速排序慢至少 10 倍。这似乎成本高得离谱!
val indices: Array[Int] = ...
class OrderingByScore extends Ordering[Int] { ... }
time { (0 to 10000).par.foreach(x => {
scala.util.Sorting.quickSort[Int](indices.take(nb))(new OrderingByScore)
})}
// Elapsed: 30 seconds
与找到here但修改为添加ord: Ordering[Int]参数的手工排序数组相比:
def sortArray1(array: Array[Int], left: Int, right: Int, ord: Ordering[Int]) = ...
time { (0 to 10000).par.foreach(x => {
sortArray1(indices.take(nb), 0, nb - 1, new OrderingByScore)
})}
// Elapsed: 19 seconds
最后,同样的代码,但使用了确切的类型 (ord: OrderingByScore):
def sortArray2(array: Array[Int], left: Int, right: Int, ord: OrderingByScore) = ...
time { (0 to 10000).par.foreach(x => {
sortArray2(indices.take(nb), 0, nb - 1, new OrderingByScore)
})}
// Elapsed: 1.85 seconds
看到每个版本之间的差异如此之大,我感到非常惊讶!
在我的示例中,索引数组是根据在另一个包含组合分数的 Doubles 数组中找到的值进行排序的。此外,排序是稳定的,因为它使用索引本身作为辅助比较。附带说明一下,为了使测试可靠,我必须在并行循环中使用“indices.take(nb)”,因为排序会修改输入数组。与把我带到这里的问题相比,这个惩罚可以忽略不计。关于要点的完整代码here。
非常欢迎您提出改进建议。但请尽量不要更改索引和分数数组的基本结构。
注意:我在 scala 2.10 REPL 中运行。
【问题讨论】:
-
也许是装箱和拆箱成本。
标签: performance scala sorting