R语言学习笔记之——多进程与并行处理包parallel

时间:2022-05-08
本文章向大家介绍R语言学习笔记之——多进程与并行处理包parallel,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

上一篇中,主要介绍了使用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秒多。