简体   繁体   中英

Why are Scala for loops so much faster than while loops for processing a sequence of distinct objects?

I recently read a post about for loops over a range of integers being slower than the corresponding while loops, which is true, but wanted to see if the same held up for iterating over existing sequences and was surprised to find the complete opposite by a large margin.

First and foremost, I'm using the following function for timing:

def time[A](f: => A) = {
    val s = System.nanoTime
    val ret = f
    println("time: " + (System.nanoTime - s) / 1e6 + "ms")
    ret
}

and I'm using a simple sequence of Integers:

val seq = List.range(0, 10000)

(I also tried creating this sequence a few other ways in case the way this sequence was accessed affected the run time. Using the Range type certainly did. This should ensure that each item in the sequence is an independent object.)

I ran the following:

time {
  for(item <- seq) {
    println(item)
  }
}

and

time {
  var i = 0
  while(i < seq.size) {
    println(seq(i))
    i += 1
  }
}

I printed the results so to ensure that we're actually accessing the values in both loops. The first code snippet runs in an average of 33 ms on my machine. The second takes an average of 305 ms .

I tried adding the mutable variable i to the for loop, but it only adds a few milliseconds. The map function gets similar performance to a for loop, as expected. For whatever reason, this doesn't seem to occur if I use an array (converting the above defined seq with seq.toArray ). In such a case, the for loop takes 90 ms and the while loop takes 40 ms.

What is the reason for this major performance difference?

The reason is: complexity. seq(i) is Θ(i) for List , which means your whole loop takes quadratic time. The foreach method, however, is linear.

If you compile with -optimize , the for loop version will likely be even faster, because List.foreach should be inlined, eliminating the cost of the lambda.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM