L'indicizzazione in array in un ciclo while è veloce sia in Scala che in Java. (Scala del ciclo "for" non è il costrutto di basso livello che Java è, in modo che non funziona nel modo desiderato.)
Così se in Java si vede
for (int i=0 ; i < array.length ; i++) sum += array(i)
a Scala si dovrebbe scrivere
var i=0
while (i < array.length) {
sum += array(i)
i += 1
}
e se fate i vostri punti di riferimento in modo appropriato, troverete alcuna differenza in termini di velocità.
Se si hanno gli iteratori in ogni caso, quindi Scala è veloce come Java nella maggior parte delle cose. Ad esempio, se si dispone di un ArrayList di doppie e in Java si aggiunge utilizzando
for (double d : arraylist) { sum += d }
poi a Scala sarai circa più veloce - se si utilizza una struttura di dati equivalente come ArrayBuffer - con
arraybuffer.foreach(sum += _)
e non troppo lontano il marchio con uno dei
sum = (0 /: arraybuffer)(_ + _)
sum = arraybuffer.sum // 2.8 only
tenere a mente, però, che c'è un rigore per la miscelazione di alto livello e di basso livello costrutti. Ad esempio, se decidi di iniziare con un array ma di utilizzare "foreach" su di esso invece di indicizzarlo, Scala deve avvolgerlo in una raccolta (ArrayOps
in 2.8) per farlo funzionare e spesso dovrà anche i primitivi.
In ogni caso, per il test di riferimento, queste due funzioni sono i tuoi amici:
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) }
Per esempio:
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
Mostraci il tuo codice di benchmarking. – Jesper