R语言多任务处理与并行运算包——foreach
时间:2022-05-08
本文章向大家介绍R语言多任务处理与并行运算包——foreach,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
相信大部分R语言初学者,在刚开始入门之处,都曾被告诫在处理多重复任务时,尽量不要使用显式的for循环,而要尽可能的使用R语言内置的apply组函数,这样可以极大地提高代码运行效率。
但是实际上除了内的apply组函数之外,你还有另外一个更好地选择,就是利用一些支持并行运算的扩展包,来发挥本地计算机的多和计算优势。
本篇要讲解的包是foreach包,这是一个支持在R语言中调用多进程功能的第三方包,之前在对比显式循环、矢量化函数以及多进程在数据抓取的效率一文中,曾经演示过具体的代码。
library("foreach")
library("doParallel")
foreach包执行任务的核心理念与传统的apply组函数基本一致,都是与split – apply – combine一致的流程,不过foreach比传统apply组函数的优越之处在于,它可以通过调用操作系统的多核运行性能来执行并行任务,这样特别是对于I/O密集型任务而言,可以大大节省代码执行效率。
foreach(..., #待输入的参数
.combine, #结果返回后执行的数据合并操作(c代表合并为向量,list代表合并为列表,rbind代表合并为数据框)
.packages=NULL, #在多进程共享的程序包(仅对于非系统安装包必备)
.export=NULL, #未在当前环境中定义的数据对象
.verbose=FALSE #是否打印运行信息
)
以上函数中,第1个参数是必备参数,即必须有输入参数,结果默认返回list。
foreach函数用于定义执行多进程任务的函数,任务的执行则需要使用%do%/%dopar%函数,前者执行的是普通的单进程任务(与apply组函数一样),后者则可以执行多进程任务。
接下来我们演示一遍整个多进程任务的过程:
首先定义一个执行函数:
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)
}
2、执行多进程函数
方案1——使用%do%函数执行普通的向量运算
library("doParallel") #加载doParallel包用于之后注册进程
library("foreach") #导入foreach包
system.time({
cl<- makeCluster(4)
registerDoParallel(cl) #进行进程注册
mydata1 <- foreach(
i=1:16, #输入等待请求的参数
.combine=rbind, #返回结果的整合
.packages = c("httr", "jsonlite","magrittr")
#多个进程共享的系统环境
) %dopar% GETPDF(i)
stopCluster(cl)
})
用户 系统 流逝
0.08 0.01 2.18
方案2——使用%dopar%函数执行多进程的运算
system.time({
cl<-makeCluster(4)
registerDoParallel(cl)
mydata2 <- foreach(i=1:16,.combine=rbind) %do% GETPDF(i)
})
用户 系统 流逝
0.39 0.03 4.53
因为%do%操作是单进程的,因而即便启动多进程环境也是徒劳。
DT::datatable(mydata1)
可以看到,%dopar%操作比%do%操作仅仅节省了0.04秒左右,但是鉴于抓包的请求频率比较高,这样多进程所节省的时间效率感知不够明显。
system.time(
mydata3 <- plyr::ldply(1:16,GETPDF)
)
用户 系统 流逝
0.32 0.00 4.54
整体时间效率比较:
ldply > %do% > %dopar%
4.54 > 4.53 > 2.18
从时间效率上来看,的确节省了将近50%的时间。如此高逼格的神器,怎能不学呢~~
- Tomcat 日志分割.
- crontab导致的频繁发送邮件的问题(r5笔记第20天)
- 再学习之Spring(依赖注入).
- 使用序列的问题ORA-02287(r5笔记第19天)
- Java多线程详解2
- Java多线程详解3
- SpringMVC处理multipart请求.
- 一条简单的sql语句运行15天的原因分析(r5笔记第17天)
- 巧用flashback database实现灵活的数据回滚(r5笔记第16天)
- Spring Cache For Redis.
- css重写checkbox样式
- 通过shell脚本同时监控多个数据库负载(r5笔记第14天)
- Java 定时器 Timer 的使用.
- 通过shell脚本来统计段大小(r5笔记第14天)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 目标检测之评价指标 - mAP
- sass的基础用法
- Golang Gin 实战(十四)| 文件托管、反向代理百度网站、自实现API网关
- ceph修复pg inconsistent
- 基于kubernetes的kong网关实战
- 移动端适配必须掌握的基本概念和适配方案
- [OHIF-Viewers]医疗数字阅片-医学影像-Redux中的reducer到底是什么,以及它为什么叫reducer?
- 【从零开始用Swift开发一个iOS应用(仿微博)】开篇-1. demo上手体验
- 数据结构与算法-二维数组中的查找
- 卷积神经网络之 - GoogLeNet / Inception-v1
- 卷积神经网络之 - Alexnet
- Linux系列之学会使用Top命令进行系统监控
- 一简单线程同步笔试题分享,欢迎纠错分享更多思路
- 卷积神经网络之-NiN 网络(Network In Network)
- 【注意力机制】空间注意力机制之Spatial Transformer Network