Replicate()与for循环?

时间:2012-11-16 07:37:00

标签: performance r for-loop replicate

有没有人知道replicate()函数在R中是如何工作的以及它与使用for循环相比有多高效?

例如,......之间存在效率差异吗?

means <- replicate(100000, mean(rnorm(50)))

和...

means <- c()
for(i in 1:100000) { 
   means <- c(means, mean(rnorm(50)))
}

(我可能在上面略微输入了一些东西,但你明白了。)

4 个答案:

答案 0 :(得分:14)

您可以对代码进行基准测试,并根据经验获得答案。请注意,我还添加了第二个for循环风格,它通过预先分配向量来避免不断增长的向量问题。

repl_function = function(no_rep) means <- replicate(no_rep, mean(rnorm(50)))
for_loop = function(no_rep) {
   means <- c()
   for(i in 1:no_rep) { 
      means <- c(means, mean(rnorm(50)))
   }
   means
}
for_loop_prealloc = function(no_rep) {
   means <- vector(mode = "numeric", length = no_rep)
   for(i in 1:no_rep) { 
      means[i] <- mean(rnorm(50))
   }
   means
}

no_loops = 50e3
benchmark(repl_function(no_loops), 
          for_loop(no_loops), 
          for_loop_prealloc(no_loops), 
          replications = 3)

                         test replications elapsed relative user.self sys.self
2          for_loop(no_loops)            3  18.886    6.274    17.803    0.894                          
3 for_loop_prealloc(no_loops)            3   3.209    1.066     3.189    0.000                          
1     repl_function(no_loops)            3   3.010    1.000     2.997    0.000                          
  user.child sys.child
2          0         0                                                                                  
3          0         0                                                                                  
1          0         0 

查看relative列,未预分配的for循环速度慢6.2倍。但是,预分配的for循环与replicate一样快。

答案 1 :(得分:8)

replicatesapply的包装器,它本身就是lapply的包装器。 lapply最终是一个用{C}编写的.Internal函数,以优化的方式执行循环,而不是通过解释器。它的主要优点是高效的内存管理,特别是与上面提到的效率极低的矢量增长方法相比。

答案 2 :(得分:1)

我与replicate的体验非常不同,这也让我感到困惑。当我使用replicatefor相比时,我的R崩溃并且我的笔记本电脑经常挂起,这让我感到惊讶,因为上面提到的原因,我也期望C编写的函数优于{ {1}}循环。例如,如果您执行以下功能,则会发现for循环比for

更快
replicate

因此system.time(for (i in 1:10) runif(1e7)) # user system elapsed # 3.340 0.218 3.558 system.time(replicate(10, runif(1e7))) # user system elapsed # 4.622 0.484 5.109 重复,10循环显然更快。如果重复100次重复,则会得到类似的结果。所以我想知道是否有人可以提供一个显示其实用特权的示例与for相比。

PS我还为for创建了一个函数,并且在比较中没有任何区别。基本上我没有提供任何显示runif(1e7)优势的例子。

答案 3 :(得分:1)

矢量化是它们之间的关键区别。我将托盘解释这一点。 R是一种高级解释的计算机语言。它可以为您完成许多基本的计算机任务。当你写

x <- 2.0

您无需告诉您的计算机

  • “2.0”是一个浮点数;
  • “x”应存储数字类型数据;
  • 它必须在内存中找到一个放置“5”的地方;
  • 必须将“x”注册为指向内存中某个位置的指针。

R本身就是这些东西。

但是,对于这样一个舒适的问题,有一个代价:它比低级语言慢。

在C或FORTRAN中,大部分内容&#34;测试是否&#34;将在编译步骤期间完成,而不是在程序执行期间完成。它们在写入之后被翻译成二进制计算机语言(0/1),但在它们运行之前。这允许编译器以最佳方式组织二进制机器代码,供计算机解释。

这与R中的矢量化有什么关系?好吧,许多R函数实际上是用编译语言编写的,比如C,C ++和FORTRAN,并且有一个小的R“包装器”。这是你的方法之间的差异。 for循环添加了机器必须对数据执行的更多test if次操作,使其更慢