7

有谁知道 replicate() 函数在 R 中是如何工作的,以及它相对于使用 for 循环的效率如何?

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

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

和...

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

(我可能在上面打了一些字,但你明白了。)

4

4 回答 4

15

您可以对代码进行基准测试并凭经验获得答案。请注意,我还添加了第二个 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.

于 2012-11-16T08:34:27.600 回答
8

replicate是 的包装器sapply,它本身就是 的包装器lapplylapply最终是一个.Internal用 C 语言编写的函数,并以优化的方式执行循环,而不是通过解释器。它的主要优点是高效的内存管理,特别是与您上面介绍的高效低效的向量增长方法相比。

于 2012-11-16T07:46:59.797 回答
1

我有一个非常不同的经历,replicate这也让我感到困惑。replicate当我使用比较时,经常会发生我的 R 崩溃和我的笔记本电脑挂起的情况for,这让我感到惊讶,正如上面提到的原因,我还期望 C 编写的函数能够胜过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复制,for循环显然更快。如果你重复 100 次,你会得到相似的结果。所以我想知道是否有人可以举一个例子来说明它与for.

PS我还为runif(1e7)and 创建了一个函数,在比较中没有区别。基本上我没有提供任何显示replicate.

于 2016-04-25T17:33:51.260 回答
1

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

x <- 2.0

你不必告诉你的电脑

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

R 自己计算这些东西。

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

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

这与 R 中的向量化有什么关系?嗯,许多 R 函数实际上是用编译语言编写的,例如 C、C++ 和 FORTRAN,并且有一个小的 R“包装器”。这是您的方法之间的区别。for循环添加test if机器必须对数据执行的进一步操作,使其变慢

于 2016-04-26T12:07:35.910 回答