import SpecializedIterator._
object Main {
def main(args: Array[String]) {
val test = Array.range(0, 100000).map(_.toLong)
measure(test.sum)
measure(test.foldLeft(0L)(_ + _))
measure(array_foldl(0L)(test)(_ + _))
measure(test.iterator.foldLeft(0L)(_ + _))
measure(test.iterator.sum)
measure(SpecializedIterator(test).sum)
measure({
var x = 0L
var i = 0
while (i < test.length) {
x += test(i)
i += 1
}
x
})
}
val warmup_time = 6000L
val measure_time = 2000L
def measure[T](what: => T) = {
def run(timelimit: Long) = {
var time_offset = System.currentTimeMillis()
var time_elapsed = 0L
var times_launched = 0L
while (time_elapsed < timelimit) {
val test = what
times_launched += 1L
time_elapsed = (System.currentTimeMillis() - time_offset)
}
(times_launched, time_elapsed)
}
System.gc()
val warmup = run(warmup_time)
System.gc()
val (times_launched, time_elapsed) = run(measure_time)
println(s"Launched $times_launched times in $time_elapsed milliseconds, ratio = ${times_launched.toDouble / time_elapsed}")
}
@inline def array_foldl[@specialized A, @specialized B](init: B)(src: Array[A])(fun: (B, A) => B) = {
var res = init
var i = 0
var len = src.length
while (i < len) {
res = fun(res, src(i))
i += 1
}
res
}
}
object SpecializedIterator {
implicit val adder_long = (0L, (x: Long, y: Long) => x + y)
@inline def apply[@specialized T](src: Array[T]) = {
new SpecializedIterator[T] {
var i = 0
val l = src.length
@inline final def hasNext = i < l
@inline final def next() = {
val res = src(i)
i += 1
res
}
}
}
}
trait SpecializedIterator[@specialized A] {
def hasNext: Boolean
def next(): A
@inline final def foreach[@specialized U](f: A => U) {
while (this.hasNext)
f(next())
}
@inline final def foldLeft[@specialized B](z: B)(op: (B, A) => B): B = {
var result = z
foreach(x => result = op(result, x))
result
}
@inline final def sum(implicit adder: (A, (A, A) => A)): A =
foldLeft(adder._1)(adder._2)
}
//Output:
Launched 2310 times in 2001 milliseconds, ratio = 1.1544227886056972
Launched 2480 times in 2012 milliseconds, ratio = 1.2326043737574552
Launched 48263 times in 2013 milliseconds, ratio = 23.97565822155986 // array_foldl
Launched 2023 times in 2012 milliseconds, ratio = 1.0054671968190856
Launched 1702 times in 2013 milliseconds, ratio = 0.8455042225534029
Launched 2146 times in 2012 milliseconds, ratio = 1.0666003976143141
Launched 48495 times in 2013 milliseconds, ratio = 24.09090909090909 // plain old loop