【问题标题】:simple R foreach example简单的 R foreach 示例
【发布时间】:2016-11-25 11:07:38
【问题描述】:

我是 R 新手,最近需要在具有特定值的列表中查找元素的索引。我尝试使用 foreach 加快操作,并比较了两种方法。在下面的代码中,“a”是列表,“b”是我们要在“a”中检索其索引的值:

library("iterators")
library("foreach")
library("doParallel")
a <- 1:200000
b <- sample(1:200000,100000,replace=TRUE)
registerDoParallel()
getDoParWorkers(); #to see the number of cores
system.time(unlist(lapply(b,function(x) which(a==x))))
system.time(foreach(i<-iter(b),.combine='c') %dopar% { which(a==b) })

输出:

Loading required package: parallel
[1] 32
   user  system elapsed 
124.648   7.460 132.114 
   user  system elapsed 
402.076  59.164  55.260 

我想知道:1)天真,为什么这个操作很慢?我还没有检查过,但我认为脚本语言可以更快地完成同样的事情。 2) 并行操作规模不应该很好,因为我有 32 个内核可用,它似乎仍然需要比预期更长的时间。 3) 实际上,我正在遍历矩阵的行,即 foreach(i

【问题讨论】:

  • 我不是专家,所以我可能是错的,但是:我知道,一般来说,编译语言比解释语言快(事实上,一旦你编译了你在机器上的可执行文件语言:每次都应解释一种脚本语言,从而导致时间损失)。然后,尽管 R 中的向量化比其他语言慢,但它还是很有用的……但是,以我的拙见(我对 R 也很陌生),与编译的非向量化语言相比,我在 R 中编写的时间要少得多: )

标签: r parallel-processing


【解决方案1】:

您进行 1e5 * 2e5 比较。这需要一些时间并不奇怪。

每个单独的which(a==x) 并没有那么慢,如果您将每个迭代单独发送给工作人员,则会有很多并行化开销。发送一堆迭代会好得多。在非 Windows 系统上,您可以使用 mclapply 做到这一点:

a <- 1:20000
b <- sample(1:20000,10000,replace=TRUE)

library(parallel)
system.time(res1 <- unlist(lapply(b,function(x) which(a==x))))
# user      system     elapsed 
#0.597       0.178       0.789 
system.time(res2 <- unlist(mclapply(b,function(x) which(a==x), 
                                    mc.preschedule = TRUE, mc.cores = 3)))
# user      system     elapsed 
#0.004       0.022       0.325 
all.equal(res1, res2)
#[1] TRUE

关于 3):可能有比并行化更好的方法(最好是矩阵代数),但这取决于您的 #stuff

【讨论】:

  • 谢谢,我已经习惯考虑并行化开销。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-04-24
  • 1970-01-01
  • 2014-09-18
  • 2013-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多