python 异步读取文件,速度变快了吗
“python 异步读取文件,速度变快了吗”
当我问出这个问题,大部分人第一反应应该是python新人,不懂异步
首先说一下我对异步的理解:
- asyncio 是 gevent + greenlet 的组合
- gevent 底层使用了libev、selectors 模块,这两个模块是检测io操作的,selectors 调用了c函数select(),是io多路复用的,其中一个参数的fds,就是等待多个文件就绪,也就是进行多个io等待
- gevent用greenlet切换协程任务用的
贴一个select模块的地址:select --- 等待 I/O 完成 — Python 3.13.0rc2 文档
白话:多个协程任务的io等待是可以同时进行的,因此减少了程序运行的总时间
asyncio的教程大致两个示例
1.asyncio.sleep(delay) 2.requests.get(url)
没毛病,时间确实减少了,但是网上没看到文件读取的示例,最后说 你们看,用了异步方式读取文件,时间减少了。测试一下 :
case1:文件大小500kb,数量3个
case2:文件大小500kb,数量500个
case3:文件大小80Mb,数量3个
case4:文件大小80Mb,数量500个
经过我的测试,以上4个case情况一样,异步没有减少读取时间,那就用case3作为例子
异步方式读取文件
jmeter.log 文件大小80Mb,数量3个
async def read_file_async(file_path):
print(f'start read {file_path}')
async with aiofiles.open(file_path, 'r') as f:
content = await f.read()
print(f'read finish')
async def main():
files = [
'jmeter.log',
'jmeter.log',
'jmeter.log'
]
now = lambda : time.time()
start = now()
task_list = [read_file_async(file) for file in files]
await asyncio.gather(*task_list)
print(now()-start)
asyncio.run(main())
运行结果
start read jmeter.log
start read jmeter.log
start read jmeter.log
read finish
read finish
read finish
0.25398802757263184
速度没有加快
接下来的问题,什么原因呢,我的答案是 我也不清楚
其实我试了asyncio、gevent、多线程、多进程、同步读取,比较下来,只有多进程会减少时间
不过不用担心,文件读取速度很快,一般情况不用考虑文件读取速度,真想提高,有人跟我说买更贵的ssd