Scala と Java のパフォーマンスの間に非常に奇妙な不一致が発生しました。Java で反転カウント ルーチンを実装し、それを 1 行ずつ Scala に移植しました。これは、すべての慣用的な Scala バージョン ( List
orを使用Stream
) が非常に遅いか、スタック オーバーフロー/メモリ不足エラーでクラッシュしたためです。しかし、このバージョンも低速でした。Java バージョンが 100000 個の整数の配列を処理するのに 22 ミリ秒かかるのに対し、Scala バージョンは 3 秒かかります。Scala バージョンの関連コードは次のとおりです。
def mergeAndCountInversions(xs: Array[Int], aux: Array[Int], left: Int, right: Int) = {
xs.copyToArray(aux)
val m = left + (right - left) / 2
var i = left
var j = m + 1
var inv: Long = 0
for (k <- left to right) {
if (i > m) {
xs(k) = aux(j)
j += 1
} else if (j > right) {
xs(k) = aux(i)
i += 1
} else if (aux(j) < aux(i)) {
xs(k) = aux(j)
j += 1
inv += (m - i) + 1
} else {
xs(k) = aux(i)
i += 1
}
}
inv
}
このルーチンのパフォーマンスを改善する方法について何かアイデアはありますか?
UPD: Scala バージョンのパフォーマンスの低さは完全に私のせいです。最初のステートメントは、配列全体を不必要に補助配列にコピーします。必要な部分だけをコピーするように変更すると、Java と同等のパフォーマンスが得られます。