對於R中循環是出了名的慢,但這裏還有另外一個問題。預先分配結果向量res更快,而且在每次迭代時附加到res。
下面我們可以比較上述版本的速度和一個簡單地以長度爲N的矢量res開始的版本,並在循環期間更改第i個元素。
fn1 <- function(N) {
res <- c()
for (i in 1:N) {
x <- rnorm(2)
res <- c(res,x[2]-x[1])
}
res
}
fn2 <- function(N) {
res <- rep(0,N)
for (i in 1:N) {
x <- rnorm(2)
res[i] <- x[2]-x[1]
}
res
}
> N <- 50000
> system.time(res1 <- fn1(N))
user system elapsed
6.568 0.256 6.826
> system.time(res2 <- fn2(N))
user system elapsed
0.452 0.004 0.496
而且,Sharpie points out,我們可以通過使用像apply
(或其親屬,sapply
和lapply
)R功能,使這稍微快一些。
fn3 <- function(N) {
sapply(1:N, function(i){ x <- rnorm(2); return(x[2] - x[1]) })
}
> system.time(res3 <- fn3(N))
user system elapsed
0.397 0.004 0.397
R列表中的第二個答案有什麼問題:res < - rnorm(10^6)-rnorm(10^6)? – ars 2009-07-23 05:07:58
@ars:你絕對是對的 - 這給出了最快的解決方案(一個數量級)。最好的建議是1.使用對矢量自然工作的函數(如rnorm); 2.如果失敗,則使用* apply函數;如果做不到這一點,請使用帶預分配的for循環。 – 2009-07-23 08:03:34