Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are Scala for loops slower than logically identical while loops? [duplicate]

Tags:

scala

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
}
like image 242
user2684301 Avatar asked Jan 27 '14 05:01

user2684301


1 Answers

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 :)

like image 64
Kevin Wright Avatar answered Oct 01 '22 02:10

Kevin Wright