计算循环内的平均值会降低性能

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了计算循环内的平均值会降低性能相关的知识,希望对你有一定的参考价值。

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

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

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

答案

当您使用其内部优化代码执行循环时,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)

以上是关于计算循环内的平均值会降低性能的主要内容,如果未能解决你的问题,请参考以下文章

循环文件映射会降低性能

openmp:线程数的增加会降低性能

Python - 循环时间性能降低

python-性能测试

过度使用硬盘会降低硬盘驱动器的性能吗?

归一化会降低分类器的性能