【问题标题】:Why is foreach() %do% sometimes slower than for?为什么 foreach() %do% 有时比 for 慢?
【发布时间】:2012-05-02 10:25:36
【问题描述】:

我第一次在 R 中使用并行化。作为第一个玩具示例,我尝试了

library(doMC)
registerDoMC()

B<-10000

myFunc<-function()
{
    for(i in 1:B) sqrt(i)
}

myFunc2<-function()
{
    foreach(i = 1:B)  %do% sqrt(i)
}

myParFunc<-function()
{
    foreach(i = 1:B) %dopar% sqrt(i)
}

我知道sqrt() 执行速度太快以至于并行化无关紧要,但我没想到的是foreach() %do% 会比for() 慢:

> system.time(myFunc())
   user  system elapsed 
  0.004   0.000   0.005 
> system.time(myFunc2())
   user  system elapsed 
  6.756   0.000   6.759 
> system.time(myParFunc())
   user  system elapsed 
  6.140   0.524   6.096 

在我见过的大多数示例中,foreach() %dopar%foreach() %do% 进行比较,而不是for()。由于在我的玩具示例中 foreach() %do%for() 慢得多,所以我现在有点困惑。不知何故,我认为这些是构造 for 循环的等效方法。有什么不同?他们曾经是等价的吗? foreach() %do% 总是慢吗?

更新:按照@Peter Fines 的回答,我更新myFunc 如下:

 a<-rep(NA,B)
 myFunc<-function()
 {
     for(i in 1:B) a[i]<-sqrt(i)
 }

这让for() 慢了一点,但并不多:

> system.time(myFunc())
   user  system elapsed 
  0.036   0.000   0.035 
> system.time(myFunc2())
   user  system elapsed 
  6.380   0.000   6.385 

【问题讨论】:

标签: r parallel-processing


【解决方案1】:

for 将运行sqrt B 次,大概每次都会丢弃答案。但是,foreach 返回一个列表,其中包含每次执行循环体的结果。无论是以并行模式还是顺序模式运行(%dopar%%do%),这都会产生相当大的额外开销。

我通过运行以下代码来确定我的答案,foreach vignette 似乎证实了这一点,其中指出“foreach 与 for 循环的不同之处在于它的返回是一个值列表,而 for 循环没有任何值并使用副作用来传达其结果。”

> print(for(i in 1:10) sqrt(i))
NULL

> print(foreach(i = 1:10) %do% sqrt(i))
[[1]]
[1] 1

[[2]]
[1] 1.414214

[[3]]
... etc

更新:我从您更新的问题中看到,上述答案不足以解释性能差异。所以我查看了source codeforeach 并且可以看到发生了很多事情!我没有试图确切地理解它是如何工作的,但是do.Rforeach.R 表明即使%do% 运行,foreach 配置的大部分仍然运行,如果可能@提供 987654334@ 选项主要是为了让您测试foreach 代码,而无需配置和加载并行后端。它还需要支持foreach 提供的更高级的嵌套和迭代工具。

代码中有对结果缓存、错误检查、调试和为每次迭代的参数创建本地环境变量的引用(例如,参见do.R 中的函数doSEQ)。我想这就是造成您观察到的差异的原因。当然,如果您在循环中运行更复杂的代码(这实际上会受益于像 foreach 这样的并行化框架),与它提供的好处相比,这种开销将变得无关紧要。

【讨论】:

  • 正确 - 这应该至少可以解释部分差异!我仍然不确定它是否能解释所有这些;查看我的问题的更新!
猜你喜欢
  • 2018-12-27
  • 2014-01-21
  • 1970-01-01
  • 1970-01-01
  • 2017-11-09
  • 2019-12-08
  • 1970-01-01
  • 2011-01-25
  • 2019-06-26
相关资源
最近更新 更多