1. import SpecializedIterator._
  2.  
  3. object Main {
  4.   def main(args: Array[String]) {
  5.     val test = Array.range(0, 100000).map(_.toLong)
  6.     measure(test.sum)
  7.     measure(test.foldLeft(0L)(_ + _))
  8.     measure(array_foldl(0L)(test)(_ + _))
  9.     measure(test.iterator.foldLeft(0L)(_ + _))
  10.     measure(test.iterator.sum)
  11.     measure(SpecializedIterator(test).sum)
  12.     measure({
  13.       var x = 0L
  14.       var i = 0
  15.       while (i < test.length) {
  16.         x += test(i)
  17.         i += 1
  18.       }
  19.       x
  20.     })
  21.   }
  22.  
  23.   val warmup_time = 6000L
  24.   val measure_time = 2000L
  25.  
  26.   def measure[T](what: => T) = {
  27.     def run(timelimit: Long) = {
  28.       var time_offset = System.currentTimeMillis()
  29.       var time_elapsed = 0L
  30.       var times_launched = 0L
  31.  
  32.       while (time_elapsed < timelimit) {
  33.         val test = what
  34.         times_launched += 1L
  35.         time_elapsed = (System.currentTimeMillis() - time_offset)
  36.       }
  37.       (times_launched, time_elapsed)
  38.     }
  39.  
  40.     System.gc()
  41.     val warmup = run(warmup_time)
  42.     System.gc()
  43.     val (times_launched, time_elapsed) = run(measure_time)
  44.     println(s"Launched $times_launched times in $time_elapsed milliseconds, ratio = ${times_launched.toDouble / time_elapsed}")
  45.   }
  46.  
  47.   @inline def array_foldl[@specialized A, @specialized B](init: B)(src: Array[A])(fun: (B, A) => B) = {
  48.     var res = init
  49.     var i = 0
  50.     var len = src.length
  51.     while (i < len) {
  52.       res = fun(res, src(i))
  53.       i += 1
  54.     }
  55.     res
  56.   }
  57. }
  58.  
  59. object SpecializedIterator {
  60.   implicit val adder_long = (0L, (x: Long, y: Long) => x + y)
  61.  
  62.   @inline def apply[@specialized T](src: Array[T]) = {
  63.     new SpecializedIterator[T] {
  64.       var i = 0
  65.       val l = src.length
  66.  
  67.       @inline final def hasNext = i < l
  68.       @inline final def next() = {
  69.         val res = src(i)
  70.         i += 1
  71.         res
  72.       }
  73.     }
  74.   }
  75. }
  76.  
  77. trait SpecializedIterator[@specialized A] {
  78.   def hasNext: Boolean
  79.   def next(): A
  80.  
  81.   @inline final def foreach[@specialized U](f: A => U) {
  82.     while (this.hasNext)
  83.       f(next())
  84.   }
  85.   @inline final def foldLeft[@specialized B](z: B)(op: (B, A) => B): B = {
  86.     var result = z
  87.     foreach(x => result = op(result, x))
  88.     result
  89.   }
  90.   @inline final def sum(implicit adder: (A, (A, A) => A)): A =
  91.     foldLeft(adder._1)(adder._2)
  92. }
  93.  
  94. //Output:
  95. Launched 2310 times in 2001 milliseconds, ratio = 1.1544227886056972
  96. Launched 2480 times in 2012 milliseconds, ratio = 1.2326043737574552
  97. Launched 48263 times in 2013 milliseconds, ratio = 23.97565822155986 // array_foldl
  98. Launched 2023 times in 2012 milliseconds, ratio = 1.0054671968190856
  99. Launched 1702 times in 2013 milliseconds, ratio = 0.8455042225534029
  100. Launched 2146 times in 2012 milliseconds, ratio = 1.0666003976143141
  101. Launched 48495 times in 2013 milliseconds, ratio = 24.09090909090909 // plain old loop