[英]Slow SQL query: using the same table in two different joins causes query to become 10x slower!
[英]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 ,速度要快得多。 您可以嘗試在代碼中替換它並再次運行基准測試。
尖頂中還有排序算法 。 所以也許只是試試那些。
基本上,無論何時你想以高性能的方式用基元進行數學運算,尖頂都是可行的方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.