上一篇中,主要介绍了使用foreach包来在R语言环境中实现任务的并行处理,其实在R语言中还有另外一个多进程包同样可以完成多进程任务,那就是parallel包,其语法与R语言内置的apply组函数以及plyr包内的_pply组函数一致。
library("parallel")
detectCores() #计算计算机核心数:
detectCores(logical=F) #获取实际物理核心数
以下可以通过这两个包来对比一下,同样的代码环境下,两者之间的性能如何。
library("httr")
library("jsonlite")
library("magrittr")
以下是一段带测试的任务代码,抓取今提头条行业研究报告:
GETPDF <- function(i){
url<-"https://index.toutiao.com/api/report"
headers<-c(
"Host"="index.toutiao.com",
"User-Agent"="Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36"
)
payload <-list("page"=1,"size"=12)
payload[["page"]]=i
web <- GET(url,add_headers(.headers = headers),query = payload)
content <- web %>% content(as="text",encoding="UTF-8") %>% fromJSON() %>% `[[`(9)
}
使用foreach提供的多进程服务进行数据提取:
library("foreach")
library("doParallel")
system.time({
cl<- makeCluster(4)
registerDoParallel(cl) #进程注册
mydata1 <- foreach(
i=1:16, #输入等待请求的参数
.combine=rbind, #返回结果的整合
.packages = c("httr","jsonlite","magrittr")
#多个进程共享的系统环境
) %dopar% GETPDF(i)
stopCluster(cl)
})
使用parallel包提供的多进程服务进行数据提取:
system.time({
cl<- makeCluster(detectCores())
all.pcg <- c("httr","jsonlite","magrittr")
worker.init <- function(p) sapply(p,library,character.only=TRUE)
clusterCall(cl, worker.init, all.pcg)
#此句用于将各个子进程的环境全部加载分配到各进程环境中
mydata2 <- parLapply(
cl, #进程环境
1:16, #遍历参数
GETPDF #测试代码语句
) %>% rlist::list.rbind()
stopCluster(cl)
})
用户 系统 流逝
0.01 0.01 1.65
使用ldply向量化函数:
system.time(
mydata3 <- plyr::ldply(1:16,GETPDF)
)
用户 系统 流逝
0.49 0.02 3.19
由测试可知,foreach、parallel、ldply的时间消耗分别为1.85、1.65、4.54,但是由于使用的api数据获取方式来测试的,可能每一次时间都会有差异,但总体上加速明显,使用foreach、parallel的耗时与普通的ldply向量化函数相比速度快了将近2秒多。