diff options
author | Paul Phillips <paulp@improving.org> | 2011-12-12 06:40:18 -0800 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-12-12 13:12:28 -0800 |
commit | 4cfc633fc6cb2ab0f473c2e5141724017d444dc6 (patch) | |
tree | 2c2467b923f369aa61baa5550bcdb2894b51bc3c /test/benchmarks/src | |
parent | d1e3b46f5bf58469bffb6f8e2ffebd932b990a5d (diff) | |
download | scala-4cfc633fc6cb2ab0f473c2e5141724017d444dc6.tar.gz scala-4cfc633fc6cb2ab0f473c2e5141724017d444dc6.tar.bz2 scala-4cfc633fc6cb2ab0f473c2e5141724017d444dc6.zip |
Range.foreach optimization.
This makes code like
0 to 100 foreach (x += _)
as fast as (often faster than, in fact) a while loop. See the
comment in Range for the gory details. More investigation should
be done regarding total impact on inlining behavior.
Review by @odersky.
Diffstat (limited to 'test/benchmarks/src')
-rw-r--r-- | test/benchmarks/src/scala/collection/immutable/range-bench.scala | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/test/benchmarks/src/scala/collection/immutable/range-bench.scala b/test/benchmarks/src/scala/collection/immutable/range-bench.scala new file mode 100644 index 0000000000..e167ff04e8 --- /dev/null +++ b/test/benchmarks/src/scala/collection/immutable/range-bench.scala @@ -0,0 +1,61 @@ +package scala.collection.immutable +package benchmarks + +object RangeTest { + // not inlined any more, needs investigation + // + // class XXS { + // private val array = Array.range(0, 100) + // def tst = { var sum = 0; for (i <- 0 until array.length) sum += array(i); sum } + // } + + var x: Int = 0 + + def foreachSum(max: Int): Int = { + var sum = 0 + 1 to max foreach (sum += _) + sum + } + def whileSum(max: Int) = { + var sum = 0 + var num = 1 + while (num <= max) { + sum += num + num += 1 + } + sum + } + + def show(max: Int, foreachNanos: Long, whileNanos: Long) { + val winner = if (foreachNanos < whileNanos) "foreachSum" else "whileSum" + val ratio = if (foreachNanos < whileNanos) foreachNanos.toDouble / whileNanos else whileNanos.toDouble / foreachNanos + println("1 to %d:, %12s wins, %.3f: foreach %.3f while %.3f".format( + max, winner, ratio, + foreachNanos.toDouble / 1000000L, + whileNanos.toDouble / 1000000L) + ) + } + + def run(max: Int) = { + val foreachFirst = util.Random.nextBoolean + val t1 = System.nanoTime + x = if (foreachFirst) foreachSum(max) else whileSum(max) + val t2 = System.nanoTime + x = if (foreachFirst) whileSum(max) else foreachSum(max) + val t3 = System.nanoTime + + val foreachNanos = if (foreachFirst) t2 - t1 else t3 - t2 + val whileNanos = if (foreachFirst) t3 - t2 else t2 - t1 + show(max, foreachNanos, whileNanos) + } + + def main(args: Array[String]): Unit = { + var max = if (args.isEmpty) 100 else args(0).toInt + while (max > 0) { + run(max) + run(max) + run(max) + max += (max / 7) + } + } +} |