我最近回答了一个关于for循环的问题.在测试我的代码速度后,我注意到在循环中使用seq()相反的速度会大大降低速度. :for
看看这个非常简单的例子.f1()和之间的唯一区别f2()是for循环序列的变化,但f1()速度是其两倍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
Run Code Online (Sandbox Code Playgroud)
为什么循环中的seq(x)速度要慢for得多1:length(x)?
dar*_*sco 24
seq是一种通用的S3方法,所以可能有一些时间丢失了调度.
seq.default几乎是100行!
你可能已经知道了seq_along,它.Primitive直接调用了一个并且比1:length(x)我在长循环中找到的最好的方法更好:
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
Run Code Online (Sandbox Code Playgroud)
使用seq_len您几乎与:运营商同时:
f3 <- function(){
x <- 1:5; y <- numeric(length(x))
for(i in seq_len(length(x))) y[i] <- x[i]^2
y
}
library(microbenchmark)
microbenchmark(f1(), f2(),f3())
Unit: microseconds
expr min lq median uq max neval
f1() 9.988 10.6855 10.9650 11.245 50.704 100
f2() 23.257 23.7465 24.0605 24.445 88.140 100
f3() 10.127 10.5460 10.7555 11.175 18.857 100
Run Code Online (Sandbox Code Playgroud)
在内部seq被调用之前做许多验证:或seq_len.