Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
460 views
in Technique[技术] by (71.8m points)

r - Why is seq(x) so much slower than 1:length(x)?

I recently answered a question pertaining to for loops. Upon testing my code's speed, I noticed that the use of seq() as opposed to : in the for loop slowed the speed down considerably.

Have a look at this very simple example. The only difference between f1() and f2() is a change in the for loop sequence, yet f1() is over twice as fast as f2().

f1 <- function() {
    x <- 1:5; y <- numeric(length(x))
    for(i in 1:length(x)) y[i] <- x[i]^2
    y
}

f2 <- function() {
    x <- 1:5; y <- numeric(length(x))
    for(i in seq(x)) y[i] <- x[i]^2
    y
}

library(microbenchmark)
microbenchmark(f1(), f2())
# Unit: microseconds
#  expr    min      lq  median     uq    max neval
#  f1() 10.529 11.5415 12.1465 12.617 33.893   100
#  f2() 25.052 25.5905 26.0385 28.759 78.553   100

Why is seq(x) so much slower in a for loop than 1:length(x) ?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

seq is a generic S3 method, so probably some time is lost dispatching. seq.default is almost 100 lines long!

You're probably already aware of seq_along, which calls a .Primitive directly and is bit better than 1:length(x) and the best method I have found for long loops:

f3 <- function(){
      x <- 1:5; y <- numeric(length(x))
      for(i in seq_along(x)) y[i] <- x[i]^2
      y
  }
>  microbenchmark(f1(), f3())
Unit: microseconds
 expr    min     lq median     uq    max neval
 f1() 27.095 27.916 28.327 29.148 89.495   100
 f3() 26.684 27.505 27.916 28.327 36.538   100

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...