我试图确定何时使用该parallel
程序包来加快运行某些分析所需的时间.我需要做的一件事是创建矩阵,比较具有不同行数的两个数据帧中的变量.我问了一个关于在StackOverflow上做有效方法的问题,并在我的博客上写了关于测试的文章.由于我对最佳方法感到满意,因此我希望通过并行运行来加快这一过程.以下结果基于带有8GB RAM的2ghz i7 Mac.令我感到惊讶的是,特别是功能parallel
包parSapply
比使用该apply
功能更糟糕.复制它的代码如下.请注意,我目前只使用我创建的两个列中的一个,但最终想要同时使用它们.
执行时间http://jason.bryer.org/images/ParalleVsApplyTiming.png
require(parallel)
require(ggplot2)
require(reshape2)
set.seed(2112)
results <- list()
sizes <- seq(1000, 30000, by=5000)
pb <- txtProgressBar(min=0, max=length(sizes), style=3)
for(cnt in 1:length(sizes)) {
i <- sizes[cnt]
df1 <- data.frame(row.names=1:i,
var1=sample(c(TRUE,FALSE), i, replace=TRUE),
var2=sample(1:10, i, replace=TRUE) )
df2 <- data.frame(row.names=(i + 1):(i + i),
var1=sample(c(TRUE,FALSE), i, replace=TRUE),
var2=sample(1:10, i, replace=TRUE))
tm1 <- system.time({
df6 <- sapply(df2$var1, FUN=function(x) { x == df1$var1 })
dimnames(df6) <- …
Run Code Online (Sandbox Code Playgroud) 我第一次在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)
}
Run Code Online (Sandbox Code Playgroud)
我知道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
Run Code Online (Sandbox Code Playgroud)
在我看过的大多数例子中,foreach() %dopar%
都是比较foreach() %do%
而不是for()
.由于foreach() %do%
比for()
我的玩具示例慢得多,我现在有点困惑.不知何故,我认为这些是构造for循环的等效方法.有什么不同?它们是否相同?是foreach() %do%
始终慢?
更新:关于@Peter罚款回答,我更新myFunc
如下:
a<-rep(NA,B) …
Run Code Online (Sandbox Code Playgroud) 为什么foreach()
有%dopar%
慢for
.一些小问题:
library(parallel)
library(foreach)
library(doParallel)
registerDoParallel(cores = detectCores())
I <- 10^3L
for.loop <- function(I) {
out <- double(I)
for (i in seq_len(I))
out[i] <- sqrt(i)
out
}
foreach.do <- function(I) {
out <- foreach(i = seq_len(I), .combine=c) %do%
sqrt(i)
out
}
foreach.dopar <- function(I) {
out <- foreach(i = seq_len(I), .combine=c) %dopar%
sqrt(i)
out
}
identical(for.loop(I), foreach.do(I), foreach.dopar(I))
## [1] TRUE
library(rbenchmark)
benchmark(for.loop(I), foreach.do(I), foreach.dopar(I))
## test replications elapsed relative user.self sys.self user.child sys.child
## …
Run Code Online (Sandbox Code Playgroud)