Scala for Comprehensionsは実際にはかなり遅いと言われています。私が与えられた理由は、Javaの制限により、渡された関数を呼び出すために、各反復で一時オブジェクトを生成する必要があるということです(後述の「reduce」など)。"for loop comprehensions"のScalaはなぜFORループに比べて非常に遅いのですか?
ISです。 .THIS ... TRUE?以下のテストではこれを補うように見えますが、なぜこれが当てはまるのか完全に理解していません。
"lambdas"または匿名関数には意味がありますが、匿名以外の関数には意味がない可能性があります。
私のテストでは、list.reduce(以下のコードを参照)に対してループを実行し、reduceに渡された関数と同じ関数が呼び出されたときでも、2倍以上速くなることがわかりました。
私はこれを非常に直感的に理解しています(Scalaライブラリはできるだけ最適になるよう注意深く作成されていたと思います)。値
- forループは:私は同じループを実行し、私は一緒に入れ試験で
、(かかわらずオーバーフローの、百万番号1を総括)は、5つの異なる方法ループのための、しかしに渡し、私は匿名関数
- list.reduceを渡し、付加機能を
- list.reduceを含むオブジェクトを作成し、forループ
- 代わりに、インライン算術関数を呼び出します 試験:分かるように最小/最大/平均(ミリ秒)
1. 27/157/64.78 2. 27/192/65.77 <--- note the similarity between tests 1,2 and 4,5 3. 139/313/202.58 4. 63/342/150.18 5. 63/341/149.99
、「理解するための」バージョン」とのオーダーであり、以下のよう
結果であったオブジェクトメンバ関数匿名と非匿名の両方の機能バージョンに対して「新しい」が実際に実行される可能性があることを意味する。
方法:以下のコード(テスト呼び出しを削除したもの)をすべてのバージョンで同じライブラリコードが実行されるように単一の.jarファイルにコンパイルしました。ヒープサイズの問題を取り除くために、各繰り返しの各テストが新しいJVM(すなわち、各テストについてscala -cp ...)で呼び出されました。あなたが言われた何
class t(val i: Int) {
def summit(j: Int) = j + i
}
object bar {
val biglist:List[Int] = (1 to 1000000).toList
def summit(i: Int, j:Int) = i+j
// Simple for loop
def forloop: Int = {
var result: Int = 0
for(i <- biglist) {
result += i
}
result
}
// For loop with a function instead of inline math
def forloop2: Int = {
var result: Int = 0
for(i <- biglist) {
result = summit(result,i)
}
result
}
// for loop with a generated object PER iteration
def forloop3: Int = {
var result: Int = 0
for(i <- biglist) {
val t = new t(result)
result = t.summit(i)
}
result
}
// list.reduce with an anonymous function passed in
def anonymousfunc: Int = {
biglist.reduce((i,j) => {i+j})
}
// list.reduce with a named function
def realfunc: Int = {
biglist.reduce(summit)
}
// test calling code excised for brevity. One example given:
args(0) match {
case "1" => {
val start = System.currentTimeMillis()
forloop
val end = System.currentTimeMillis()
println("for="+(end - start))
}
...
}
'.reduce'は" for comprehensions "とは関係ありません –
補足として、一般的なケースでこのオーバーヘッドを取り除くことを目的としたscalaコンパイラプラグインがあります:https://code.google.com/p/scalacl/wiki/ScalaCLPlugin私はそれを自分で試していない。 –
実際、最初の3つのテストはfor-comprehensionsを使用しており、それらのタイミングを 'reduce'と比較しています。 –