R语言中for循环的并行处理
前言
本文用于记录笔者在将R语言中的for语句并行化处理中的一些问题。
实验
这里使用foreach和doParallel包提供的函数实现for语句的并行处理。
for语句脚本
func <- function(x, y, z) {
return(x^y/z)
}
# >>> main <<<
x <- 2
y <- 3
z <- 1:100000
start <- (proc.time())[3][[1]]
a <- 0
for (i_z in z) {
a <- a + func(x, y, i_z)
}
end <- (proc.time())[3][[1]]
print(paste('Result = ', round(a, 2), ', time = ', (end-start), 's', sep=''))
输出:
[1] "Result = 96.72, time = 0.177s"
并行化版本
library(foreach)
library(doParallel)
func <- function(x, y, z) {
return(x^y/z)
}
# >>> main <<<
x <- 2
y <- 3
z <- 1:100000
start <- (proc.time())[3][[1]]
cl <- makeCluster(12)
registerDoParallel(cl)
a <- foreach(z=z, .combine='rbind') %dopar% func(x, y, z)
a <- sum(a)
stopCluster(cl)
end <- (proc.time())[3][[1]]
print(paste('Result = ', round(a, 2), ', time = ', (end-start), 's', sep=''))
输出:
[1] "Result = 96.72, time = 37.988s"
总结
-
这里发现并行化所用时间大于非并行化所用过的时间,是因为需要执行的操作(func函数)过于简单,而foreach处理时会有额外的资源消耗。此时foreach额外消耗的资源远大于需要执行的操作所需的资源,因此会导致并行化后反而使用的时间增加了。所以对于一些复杂的操作比较适合使用并行化的策略。
-
foreach函数的.packages参数可以为并行化函数传递额外需要的包。
-
foreach中的参数为需要在func中循环的变量,其他固定的变量则在func中传入。参数可以是data.frame类型。