Lập chỉ mục thành các mảng trong một vòng lặp while nhanh như trong Scala như trong Java. (Scala của "cho" vòng lặp không phải là xây dựng ở mức độ thấp rằng Java là, do đó sẽ không làm việc theo cách bạn muốn.)
Vì vậy, nếu trong Java mà bạn nhìn thấy
for (int i=0 ; i < array.length ; i++) sum += array(i)
trong Scala bạn nên viết
var i=0
while (i < array.length) {
sum += array(i)
i += 1
}
và nếu bạn làm điểm chuẩn của mình một cách thích hợp, bạn sẽ thấy không có sự khác biệt về tốc độ.
Nếu bạn có trình lặp nào, thì Scala nhanh bằng Java trong hầu hết mọi thứ. Ví dụ, nếu bạn có một ArrayList của đôi và trong Java bạn thêm chúng vào sử dụng
for (double d : arraylist) { sum += d }
sau đó trong Scala bạn sẽ có xấp xỉ càng nhanh - nếu sử dụng một cấu trúc dữ liệu tương đương như ArrayBuffer - với
arraybuffer.foreach(sum += _)
và không quá xa nhãn hiệu với một trong hai
sum = (0 /: arraybuffer)(_ + _)
sum = arraybuffer.sum // 2.8 only
Hãy ghi nhớ, tuy nhiên, rằng có một hình phạt để trộn các cấu trúc cấp cao và cấp thấp. Ví dụ, nếu bạn quyết định bắt đầu với một mảng nhưng sau đó sử dụng "foreach" trên nó thay vì chỉ mục vào nó, Scala phải bọc nó trong một bộ sưu tập (ArrayOps
trong 2.8) để làm cho nó hoạt động, và thường sẽ phải các nguyên thủy là tốt.
Dù sao, để thử nghiệm benchmark, hai chức năng là bạn bè:
def time[F](f: => F) = {
val t0 = System.nanoTime
val ans = f
printf("Elapsed: %.3f\n",1e-9*(System.nanoTime-t0))
ans
}
def lots[F](n: Int, f: => F): F = if (n <= 1) f else { f; lots(n-1,f) }
Ví dụ:
val a = Array.tabulate(1000000)(_.toDouble)
val ab = new collection.mutable.ArrayBuffer[Double] ++ a
def adSum(ad: Array[Double]) = {
var sum = 0.0
var i = 0
while (i<ad.length) { sum += ad(i); i += 1 }
sum
}
// Mixed array + high-level; convenient, not so fast
scala> lots(3, time(lots(100,(0.0 /: a)(_ + _))))
Elapsed: 2.434
Elapsed: 2.085
Elapsed: 2.081
res4: Double = 4.999995E11
// High-level container and operations, somewhat better
scala> lots(3, time(lots(100,(0.0 /: ab)(_ + _))))
Elapsed: 1.694
Elapsed: 1.679
Elapsed: 1.635
res5: Double = 4.999995E11
// High-level collection with simpler operation
scala> lots(3, time(lots(100,{var s=0.0;ab.foreach(s += _);s})))
Elapsed: 1.171
Elapsed: 1.166
Elapsed: 1.162
res7: Double = 4.999995E11
// All low level operations with primitives, no boxing, fast!
scala> lots(3, time(lots(100,adSum(a))))
Elapsed: 0.185
Elapsed: 0.183
Elapsed: 0.186
res6: Double = 4.999995E11
Hiện chúng tôi đang chuẩn của bạn. – Jesper