1

For loops are know to be quite slow in R. I would like to know if the same is true for while loop.

If so, is there a way to optimize while loop in R? For example for the for loop the apply functions play a good job but I don't know an analogue for the while loop.

Even Hadley in his book (Advanced R) is quite vague about how to optimize a while loop.

adaien
  • 1,932
  • 1
  • 12
  • 26
  • "For loops are know to be quite slow in R." That's simply wrong. `for` loops are fast. What you do inside the loop is slow (in comparison to vectorized operations). I would expect a `while` loop to be slower than a `for` loop since it needs to test a condition before each iteration. Keep in mind that R is an interpreted language, i.e., there are no compiler optimizations. – Roland Mar 24 '16 at 12:05
  • @Roland Do you think that if we are to write a while loop for a bisection method for example, if we optimize what's inside the while loop we can achieve a proper speed? – adaien Mar 24 '16 at 12:12
  • What is a "proper" speed? – Roland Mar 24 '16 at 12:18
  • Comparable to the already built-in function in R for the same tasks – adaien Mar 24 '16 at 12:31
  • 1
    `apply` is not faster than a `for` loop: http://stackoverflow.com/a/2276001/1412059 – Roland Mar 24 '16 at 13:12
  • I haven't mentioned any apply function, I was just referring to examples like the cumsum provided below where optimized code is faster – adaien Mar 24 '16 at 13:15
  • 1
    "For example for the for loop the apply functions play a good job but I don't know an analogue for the while loop." – Roland Mar 24 '16 at 13:16
  • In cases like the link yes apply it's not faster, in other cases yes. The answer is accepted however, thank you – adaien Mar 24 '16 at 13:17
  • 2
    No, `apply` is never faster than a well written `for` loop. Of course, it helps avoiding some popular mistakes you can do with `for` loops (like growing an object). – Roland Mar 24 '16 at 13:19

1 Answers1

5

"For loops are know to be quite slow in R." That's simply wrong. for loops are fast. What you do inside the loop is slow (in comparison to vectorized operations). I would expect a while loop to be slower than a for loop since it needs to test a condition before each iteration. Keep in mind that R is an interpreted language, i.e., there are no compiler optimizations. Also, function calls in R are not slow per se, but still there is a lot going on during a function call and that adds up. Vectorized operations avoid repeated function calls.

It's hard to come up with a fair comparison between both loop construct, but here we go:

library(microbenchmark)

microbenchmark(
  for (i in seq_len(1e6)) i,
  {i <- 1; while (i <= 1e6) {i <- i+1}},
  times = 10, unit = "relative"
)

#Unit: relative
#                                                             expr      min       lq    mean   median       uq      max neval cld
#                                      for (i in seq_len(1e+06)) i 1.000000 1.000000 1.00000 1.000000 1.000000  1.00000    10  a 
# {     i <- 1     while (i <= 1e+06) {         i <- i + 1     } } 8.987293 8.994548 9.14089 9.019795 9.036116 10.07227    10   b

The while loop needs to test the condition, assign to i and call + at each iteration.

If you must use a while loop (often it can be avoided) and performance is important, the best solution is implementing it as compiled code which can be called from R. The Rcpp package makes this very easy. In some cases byte compilation as offered by the compiler package can also speed up R loops, but (well written) actual compiled code will always be faster.

Roland
  • 127,288
  • 10
  • 191
  • 288
  • Thanks for reply, but I can't still figure out why for loops are not slow. If you consider this example n=1000000 sum=0 system.time(for (i in 1:n) {sum=sum+i}) system.time(cumsum(as.numeric(1:n))) they are actually slower but it doesn't seem to be any unnecessary operation inside the for – adaien Mar 24 '16 at 12:42
  • 1
    You have n (actually 2 times n) function calls that achieve the same as one function call. Why are you surprised that the latter is faster? – Roland Mar 24 '16 at 12:47
  • In *compiled* code, which must be faster than interpreted code. – Roland Mar 24 '16 at 12:50
  • Can you please explain this more clearly: "I would expect a while loop to be slower than a for loop since it needs to test a condition before each iteration"? You seem to be right, but I wonder why this wouldn't be true for a FOR loop as well. At each iteration, the loop needs to check whether the index variable is still within the range, doesn't it? – RHertel Mar 24 '16 at 12:50
  • 1
    @RHertel I think there are all kinds of optimizations for what the `for` loop does. I would be surprised if it actually checks if the index is within the bounds. – Roland Mar 24 '16 at 12:53
  • Alright, I understand. In FOR loops it is essentially always the same condition, and that test can be optimized under the hood, whereas a while loop can have any condition. Got it. Thanks! – RHertel Mar 24 '16 at 12:54
  • @Roland So for loops ARE actually slower because it's interpreted code against compiled code? – adaien Mar 24 '16 at 12:55
  • R `for` loops are slower than compiled code (that does the same). Full stop. However, that's not because the `for` loop is slow, but because of all the stuff that happens inside it (including function calls) is relatively slow. Read [this](https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Evaluation) to learn about all the stuff that happens during a function call. – Roland Mar 24 '16 at 12:59
  • Once acknowledge that while loops are slower, is there a way to translate while loops in compiled code in order to make it faster? – adaien Mar 24 '16 at 13:06
  • 1
    Yes, of course. You can try if byte compilation (i.e., the `compiler` package) helps or you can use Rcpp (if you have some minimal knowledge of C/C++). – Roland Mar 24 '16 at 13:08
  • Thanks, all I needed :) You can edit your answer if you'd like – adaien Mar 24 '16 at 13:10
  • What should I edit there? I think it answers the question as asked. – Roland Mar 24 '16 at 13:11
  • This part was not answered in your question "If so, is there a way to optimize while loop in R? " – adaien Mar 24 '16 at 13:12