【问题标题】:Calculating the mean within a loop reduces performance计算循环内的平均值会降低性能
【发布时间】:2019-07-15 15:09:29
【问题描述】:

考虑第一个例子: 它计算循环内的平均值。

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

我只是想知道,为什么两种代码的性能差异如此之大?使用循环时应该注意哪些地方?

【问题讨论】:

  • Why are loops slow in R?的可能重复
  • 不重复。我的问题非常具体。两者都使用循环。但是第一个非常慢,而第二个则不是。
  • 副本解释了它:在第一种情况下,您调用 mean 函数 100,000 次,而在第二种情况下,您调用 cumsum 函数,该函数经过优化以执行此操作而无需所有多次调用mean 的开销

标签: r performance loops


【解决方案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)

【讨论】:

    猜你喜欢
    • 2021-06-29
    • 2016-12-22
    • 2014-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-09
    • 2018-08-14
    • 2014-02-08
    相关资源
    最近更新 更多