いくつかのベンチマークを実行しましたが、説明の仕方がわからない結果が得られました。
一言で言えば状況:
ジェネリック配列で同じ(計算量が多い)ことを行う2つのクラスがあり、どちらも特殊化を使用しています(@specialized
、後で@spec
)。1 つのクラスは次のように定義されます。
class A [@spec T] {
def a(d: Array[T], c: Whatever[T], ...) = ...
...
}
2番目: (シングルトン)
object B {
def a[@spec T](d: Array[T], c: Whatever[T], ...) = ...
...
}
2 番目のケースでは、パフォーマンスが大幅に低下します。なぜこれが起こることができますか?(注: 現時点では、Java バイトコードも Scala コンパイラの内部もよく理解していません。)
詳細:
完全なコードはこちら: https://github.com/magicgoose/trashbox/tree/master/sorting_tests/src/magicgoose/sorting
これは、Java からリッピングされたソート アルゴリズムであり、(ほぼ) 自動で Scala に変換され、比較操作が一般的なものに変更されています。ボクシングせずにプリミティブ型とのカスタム比較を使用できるようにします。加えて、単純なベンチマーク (さまざまな長さでのテスト、JVM のウォームアップと平均化)
結果は次のようになります: (左の列は元の Java ですArrays.sort(int[])
)
JavaSort | JavaSortGen$mcI$sp | JavaSortGenSingleton$mcI$sp
length 2 | time 0.00003ms | length 2 | time 0.00004ms | length 2 | time 0.00006ms
length 3 | time 0.00003ms | length 3 | time 0.00005ms | length 3 | time 0.00011ms
length 4 | time 0.00005ms | length 4 | time 0.00006ms | length 4 | time 0.00017ms
length 6 | time 0.00008ms | length 6 | time 0.00010ms | length 6 | time 0.00036ms
length 9 | time 0.00013ms | length 9 | time 0.00015ms | length 9 | time 0.00069ms
length 13 | time 0.00022ms | length 13 | time 0.00028ms | length 13 | time 0.00135ms
length 19 | time 0.00037ms | length 19 | time 0.00040ms | length 19 | time 0.00245ms
length 28 | time 0.00072ms | length 28 | time 0.00060ms | length 28 | time 0.00490ms
length 42 | time 0.00127ms | length 42 | time 0.00096ms | length 42 | time 0.01018ms
length 63 | time 0.00173ms | length 63 | time 0.00179ms | length 63 | time 0.01052ms
length 94 | time 0.00280ms | length 94 | time 0.00280ms | length 94 | time 0.01522ms
length 141 | time 0.00458ms | length 141 | time 0.00479ms | length 141 | time 0.02376ms
length 211 | time 0.00731ms | length 211 | time 0.00763ms | length 211 | time 0.03648ms
length 316 | time 0.01310ms | length 316 | time 0.01436ms | length 316 | time 0.06333ms
length 474 | time 0.02116ms | length 474 | time 0.02158ms | length 474 | time 0.09121ms
length 711 | time 0.03250ms | length 711 | time 0.03387ms | length 711 | time 0.14341ms
length 1066 | time 0.05099ms | length 1066 | time 0.05305ms | length 1066 | time 0.21971ms
length 1599 | time 0.08040ms | length 1599 | time 0.08349ms | length 1599 | time 0.33692ms
length 2398 | time 0.12971ms | length 2398 | time 0.13084ms | length 2398 | time 0.51396ms
length 3597 | time 0.20300ms | length 3597 | time 0.20893ms | length 3597 | time 0.79176ms
length 5395 | time 0.32087ms | length 5395 | time 0.32491ms | length 5395 | time 1.30021ms
後者は内部object
で定義されたもので、ひどいものです (約 4 倍遅い)。
更新 1
scalacoptimise
オプションを使用して、または使用せずにベンチマークを実行しましたが、顕著な違いはありません (コンパイルが遅いだけですoptimise
)。