Vector.min
として実装されます
def min[B >: A](implicit cmp: Ordering[B]): A = {
if (isEmpty)
throw new UnsupportedOperationException("empty.min")
reduceLeft((x, y) => if (cmp.lteq(x, y)) x else y)
}
プロフィールを作成するとき
Vector.fill(1000000)(scala.util.Random.nextLong).min
それは高速で、ボクシングやアンボクシングは行われていません。ただし、明らかに同等のものを書く場合
val cmp = implicitly[Ordering[Long]]
Vector.fill(1000000)(scala.util.Random.nextLong).reduceLeft((x, y) => if (cmp.lteq(x, y)) x else y)
実行速度は約10倍遅くなります(ランダムでの時間を無視すると、それ以外の場合はこれを支配します。そうです、ベンチマークをウォームアップしました...)。
最初のバージョンはボクシングのパフォーマンスの低下をどのように回避していますか?
編集:これが私のプロファイリングコードです:
val cmp = implicitly[Ordering[Long]]
def randomLongs = Vector.fill(1000000)(scala.util.Random.nextLong)
def timing[R](f: => R): (Long, R) = {
val startTime = System.nanoTime
val result = f
((System.nanoTime - startTime) / 1000000, result)
}
def minTiming = { val r = randomLongs; timing(r.min)._1 }
def reduceLeftTiming = { val r = randomLongs; timing(r.reduceLeft((x, y) => if (cmp.lteq(x, y)) x else y))._1 }
while(true) {
println((minTiming, reduceLeftTiming))
}
min
約20ミリ秒、約200ミリ秒の時間を使用していreduceLeft
ます。YourKit
;を使用してこのコードのプロファイルを作成しました。これは、ボクシングが発生しないことを示すコールツリーのスクリーングラブです。min