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