Python : async和await、asyncio与aiofiles
aiofiles、aiohttp、asyncio是python异步生态的三件套。其中,asycnio运行时框架,aifiles主要是io读写库;aiohttp主要是客户端web库(sanic 是web服务端异步库)。
一、真假异步
import asyncio
import time
import math
import pandas as pd## cpu compute type
async def async_main(n):total = 0for i in range(n):total = total+ math.sin(i)return totalasync def async_main_k_times(n,k):tasks = []for i in range(k):task = asyncio.create_task(async_main(n))tasks.append(task)L = await asyncio.gather(*tasks)return Ldef sync_main(n):total = 0for i in range(n):total = total+ math.sin(i)return total ## IO type
file = r"C:\Users\songroom\Desktop\scores.csv"
async def async_io():df = pd.read_csv(file,sep =",",encoding="ANSI")return dfasync def async_io_k_times(counts):tasks = []for i in range(counts):task = asyncio.create_task(async_io())tasks.append(task)L = await asyncio.gather(*tasks)return L
def sync_io():df = pd.read_csv(file,sep =",",encoding="ANSI")return dfn = 1000000
k = 10
t0 = time.time()
asyncio.run(async_main(n))
t1 = time.time()
asyncio.run(async_main_k_times(n,k))
t2 = time.time()
sync_main(n)
t3 = time.time()
print(f"cpu compute type: n :{n} k:{k}")
print(f"async_main: cost time {t1-t0} ")
print(f"async_main_k_times : cost time {t2-t1} ")
print(f"sync_main: cost time {t3-t2} ")counts = 100
t4 = time.time()
asyncio.run(async_io())
t5 = time.time()
sync_io()
t6 = time.time()
asyncio.run(async_io_k_times(counts))
t7 = time.time()
print(f"io type : io counts :{counts}")
print(f"async_io: cost time {t5-t4} ")
print(f"async_io_k_times : cost time {t7-t6} ")
print(f"sync_io: cost time {t6-t5} ")
为什么会出现异步后,效率反而下降了?其实,最主要的原因,上面核心代码并没有实现真正的异步。比如,pd.read_csv,这是一个同步堵塞的IO操作。
二、如何真异步io
aiofiles是python的异步io库,,具体详细资料可见:
https://github.com/Tinche/aiofiles
主要使用方法如下:
async def asyc_wirte(file):# 异步方式执行with操作,修改为 async withasync with aiofiles.open(file,"w",encoding="utf-8") as fp:await fp.write("hello world ")print("数据写入成功")async def asyc_read(file):async with aiofiles.open(file,"r",encoding="utf-8") as fp:content = await fp.read()print(content)async def asyn_read_line(file):async with aiofiles.open(file,"r",encoding="utf-8") as fp:# 读取每行async for line in fp:print(line)
可以把上面的代码重新改写一下,csv读部分变成真异步(同时换了一个更大size的csv文件):
import asyncio
import time
import math
import pandas as pd
import aiofiles
import io## cpu compute type
async def async_main(n):total = 0for i in range(n):total = total+ math.sin(i)return totalasync def async_main_k_times(n,k):tasks = []for i in range(k):task = asyncio.create_task(async_main(n))tasks.append(task)L = await asyncio.gather(*tasks)return Ldef sync_main(n):total = 0for i in range(n):total = total+ math.sin(i)return total ## pandas read_csvasync def async_pandas_io(file):df = pd.read_csv(file,sep =",",encoding="ANSI")return dfasync def async_pandas_io_k_times(counts,file):tasks = []for i in range(counts):task = asyncio.create_task(async_pandas_io(file))tasks.append(task)L = await asyncio.gather(*tasks)return L
## pandas 同步read_csv
def sync_pandas_io(file):df = pd.read_csv(file,sep =",",encoding="ANSI")return df## aiofiles read_csv async def async_aio_write(file):# 异步方式执行with操作,修改为 async withasync with aiofiles.open(file,"w",encoding="utf-8") as fp:await fp.write("hello world ")print("数据写入成功")async def async_aio_read(file):async with aiofiles.open(file,"r",encoding="utf-8") as fp:content = await fp.read()df = pd.read_csv(io.StringIO(content), sep=",")#print(df)return dfasync def async_aio_read_line(file):async with aiofiles.open(file,"r",encoding="utf-8") as fp:# 读取每行async for line in fp:print(line)async def async_aio_read_k_times(counts,file):tasks = []for i in range(counts):task = asyncio.create_task(async_aio_read(file))tasks.append(task)L = await asyncio.gather(*tasks)return Lfile = r"C:\Users\songroom\Desktop\scores.csv"
n = 1000000
k = 10
t0 = time.time()
asyncio.run(async_main(n))
t1 = time.time()
asyncio.run(async_main_k_times(n,k))
t2 = time.time()
sync_main(n)
t3 = time.time()
print(f"cpu compute type: n :{n} k:{k}")
print(f"async_main: cost time {t1-t0} ")
print(f"async_main_k_times : cost time {t2-t1} ")
print(f"sync_main: cost time {t3-t2} ")counts = 100
t4 = time.time()
asyncio.run(async_pandas_io(file))
t5 = time.time()
sync_pandas_io(file)
t6 = time.time()
asyncio.run(async_pandas_io_k_times(counts,file))
t7 = time.time()
asyncio.run(async_aio_read_k_times(counts,file))
t8 = time.time()print(f"io type : io counts :{counts}")
print(f"async_pandas_io: cost time {t5-t4} ")
print(f"async_pandas_io_k_times : cost time {t7-t6} ")
print(f"sync_pandas_io: cost time {t6-t5} ")
print(f"async_aio_read: cost time {t8-t7} ")
输出结果如下:
cpu compute type: n :1000000 k:10
async_main: cost time 0.1399977207183838
async_main_k_times : cost time 1.7040011882781982
sync_main: cost time 0.16300249099731445
io type : io counts :100
async_pandas_io: cost time 0.02899909019470215
async_pandas_io_k_times : cost time 0.7789931297302246
sync_pandas_io: cost time 0.013007164001464844
async_aio_read: cost time 0.7399976253509521
上面的结果表明:
1、异步的效果:处理100次读csv文件在真异步下,需要0.73秒,还包括转成dataframe的时间,如果只是字符串还更快;和和同步的100次读csv约1.3秒相比,大约时间减少近50%;
2、async_aio_read和async_pandas_io_k_times两者时间差不多,不知道原因为什么,是不是同步在用了线程池后,实际效果和异步下用了线程池的效果差不多所致?
Python : async和await、asyncio与aiofiles相关推荐
- 【Python】asyncio的使用(async、await关键字)
1.协程 相比于线程和进程,协程显得更加轻量级,因为它是在函数直接进行切换,所以开销更小,也更灵活.之前有介绍过greenlet.gevent这样的协程库([python]协程(greenlet.ge ...
- python爬虫 asyncio aiohttp aiofiles 单线程多任务异步协程爬取图片
python爬虫 asyncio aiohttp aiofiles 多任务异步协程爬取图片 main.py """=== coding: UTF8 ==="&q ...
- python async await报错_Python 3.7.7 发布 支持async并await现在为保留关键字
Python 3.7.7 发布了,这是一个 bug 修复版本.2020 年中之前将持续更新 3.7 系列的 bug 修复版本,并直到 2023 年中之前持续提供安全修复版本. 目前 3.8 已经是最新 ...
- python gevent async_python的异步初体验(gevent、async、await)
网络爬虫,这种io高密集型的应用由于大部分的时间在等待响应方面,所以CPU的使用率一直不高,速度也不快,为了解决这些问题,我们使用异步的方式来进行爬虫程序. 串行的时候,如果我们要爬一个网站,那么我们 ...
- python中await async_[转载]python中的await和async
原文https://blog.csdn.net/Likianta/article/details/90123678 from time import sleep, time def demo1(): ...
- asyncio 文件io高并发_python教程:使用 async 和 await 协程进行并发编程
python 一直在进行并发编程的优化, 比较熟知的是使用 thread 模块多线程和 multiprocessing 多进程,后来慢慢引入基于 yield 关键字的协程. 而近几个版本,python ...
- python async await threading_Python - 从使用线程到使用 async/await
async/await 是一种异步编程方法,还有两种你可能听过,1. 回调 2. Promise (写过 JavaScript 的肯定很熟悉了) 异步意味着任务不会阻塞,比如,如果我要下载一个比较忙的 ...
- Python3.7 高级编程之 async/await asyncio 事件循环的使用
什么是事件循环: 事件循环是每个 asyncio 应用的核心. 事件循环会运行异步任务和回调,执行网络 IO 操作,以及运行子进程. 说简单点就是由于python是单线程的 程序在执行中会将所有任务放 ...
- Python async模块使用(杂文)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一.什么是 generator(生成器)? generator的实现方式 二.使用asyncio 实现异步io 三.aioh ...
- python异步编程框架asyncio
并行和并发 并行:在操作系统中是指,一组程序按独立异步的速度执行,无论从微观还是宏观,程序都是一起执行的. 并发:在操作系统中,是指一个时间段中有多个已启动的程序运行在同一个执行机上,多个程序交替着切 ...
最新文章
- linux下的重要服务dns
- mysql创建表选择字段的时候下尽量小
- 概率统计笔记:威沙特分布(Wishart Distribution)
- java.lang.InstantiationException 不能实例化某个对象
- linux awk 教程,Linux awk使用案例教程
- qt爬取网页信息_豆瓣TOP250数据爬取
- Java的GUI学习七(鼠标事件)
- 【车间调度】基于matlab GUI遗传算法求解车间调度问题【含Matlab源码 049期】
- ZXing拍码后区分扫描到的是一维码、二维码、其他码,android音视频面试
- 雪花算法(SnowFlake)
- Fragstats计算景观格局指数(初学指南)
- express-urlrewrite express url重写
- 2.Hadoop_入门_模板机IP地址和主机名称配置
- AtCoder Beginner Contest 228
- 中介分析(四)- 因果中介分析
- 风口上的猪-中国牛市
- 【Unity3D】3dsmax中带Vray材质的3D模型的导入
- 爱奇艺大裁员,互联网的苦日子来了…
- 综合布线设计与实践知识点总结
- 免费好用的APP你值得一试