Why are Scala for loops slower than logically identical while loops?

scala

Solution

The main (but not only) reason why they're different is boxing.

In the code:

for (i <- 0 until n) println(s"for loop with $i")

You're passing an anonymous function `println(s"for loop with $i")` into the comprehension `for (i <- 0 until n)`. It's equivalent to:

(0 until n) foreach (i =>
  println(s"for loop with $i")
}

That function is erased in the bytecode, which means that `i` can't be a primitive `int`, it has to be boxed as an `Integer` instead. Java doesn't have Fixnum references to avoid this cost in the same way that e.g. Smalltalk does (especially frustrating, given how much older smalltalk is!)

Using `-optimize` can help in some cases, especially in trunk builds of scalac.

You can also use scalaxy/loops to speed things up :)

Problem

I love the power of Scala's for comprehensions and the way they integrate with any monadic type with map and flatMap. However, I'd also like to do simple integer loops without a major speed penalty. Why doesn't Scala have the following two logically identical loops run with similar runtime performance or even compile into similar byte code? ``` // This is slow... for (i <- 0 until n) println(s"for loop with $i") // This runs much faster. It runs roughly at the same speed as Java code doing an identical while or for loop. var i = 0; while (i < n) { println(s"while loop with $i") i += 1 } ```

Original source

Related problems