summaryrefslogtreecommitdiff
path: root/test/benchmarks/src/scala/collection/immutable/range-bench.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-12-12 06:40:18 -0800
committerPaul Phillips <paulp@improving.org>2011-12-12 13:12:28 -0800
commit4cfc633fc6cb2ab0f473c2e5141724017d444dc6 (patch)
tree2c2467b923f369aa61baa5550bcdb2894b51bc3c /test/benchmarks/src/scala/collection/immutable/range-bench.scala
parentd1e3b46f5bf58469bffb6f8e2ffebd932b990a5d (diff)
downloadscala-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/scala/collection/immutable/range-bench.scala')
-rw-r--r--test/benchmarks/src/scala/collection/immutable/range-bench.scala61
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)
+ }
+ }
+}