考虑第一个示例: 它计算循环内的均值。
st <- Sys.time() #Starting Time
set.seed(123456789)
vara <- c()
sda <- c()
mvara <- c() #store mean
msda <- c() #store mean of standard deviation
K <- 100000
for(i in 1:K) {
a <- rnorm(30)
vara[i] <- var(a)
sda[i] <- sd(a)
mvara[i] <- mean(mvara)
msda[i] <- mean(msda)
}
et <- Sys.time()
et-st #time taken by code (approx more than one minute)
考虑相同的代码,除了在循环外计算相同的均值。
st <- Sys.time() #Starting Time
set.seed(123456789)
vara <- c()
sda <- c()
K <- 100000
for(i in 1:K) {
a <- rnorm(30)
vara[i] <- var(a)
sda[i] <- sd(a)
}
mvara <- cumsum(vara)/ (1:K)
msd <- cumsum(sda)/ (1:K)
et <- Sys.time() #less than 5 seconds
我只是想知道,为什么两个代码的性能差异如此之大?使用循环时应该注意的地方?
答案 0 :(得分:1)
R使用内部优化的代码执行循环时最快。我对造成这种情况的原因的理解很差(上面评论中的主题有更多有学识的人的解释),但我相信其中一些原因与内存预分配有关,还有一些与将问题转化为更多问题的方式有关有效的片段。
通过首先创建所有随机数,然后立即求解整个表,而不是交换,可以使您的代码“循环外”的速度提高约20倍(在我的系统上,从7.17秒变为0.43秒)在循环中的这两个任务之间。那就是使用dplyr
;我认为data.table
解决方案的速度可能会高出5到10倍,特别是考虑到大量的群组。
library(dplyr)
set.seed(123456789)
K <- 100000
n <- 30
a_df <- data.frame(trial = rep(1:K, each = 30),
val = rnorm(K*n))
results <- a_df %>%
group_by(trial) %>%
summarize(vara = var(val),
sda = sd(val)) %>%
mutate(mvara = cumsum(vara) / trial,
msd = cumsum(sda) / trial)