簡體   English   中英

Scala quickSort使用Ordering [T]速度慢10倍

[英]Scala quickSort 10x slower when using Ordering[T]

我正在根據自定義排序對整數索引進行一些排序。 我發現這里使用的Ordering [T]使用直接調用compare方法比使用手工制作的quickSort慢至少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

與手工制作的sortArray相比, 此處可以修改以添加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

我很驚訝地發現每個版本之間存在這樣的差異!

在我的示例中,indices數組基於在包含組合分數的另一個Doubles數組中找到的值進行排序。 此外,排序是穩定的,因為它使用索引本身作為次要比較。 另外,為了使測試可靠,我必須在並行循環中使用“indices.take(nb)”,因為排序會修改輸入數組。 與我帶來的問題相比,這種懲罰可以忽略不計。 對要點的完整代碼在這里

你的建議很受歡迎改進..但盡量不要改變索引和分數數組的基本結構。

注意:我在scala 2.10 REPL中運行。

問題是scala.math.Ordering不是專門的。 所以每次調用的是具有基本類似的比較方法的時間Int ,類型的兩個參數Int被裝箱為java.lang.Integer 這會產生許多短暫的物體,這會大大減慢速度。

尖頂庫有一個專門版本的Ordering,名為spire.algebra.Order ,速度要快得多。 您可以嘗試在代碼中替換它並再次運行基准測試。

尖頂中還有排序算法 所以也許只是試試那些。

基本上,無論何時你想以高性能的方式用基元進行數學運算,尖頂都是可行的方法。

此外,如果您想要信任結果,請使用適當的微基准測試工具(如ThymeJMH)進行基准測試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM