python同步读取文件vs多线程读取vs异步读取文件aiofiles
- 编程
- 2021-09-01
- 1544
文件夹内采集了7w多篇txt文章 读取每篇文章内容比较耗时,所以想着有个异步库aiofiles 测试一下同步与异步效率的差别
同步代码:
import os
import time
def eachfile(path):
file_list = os.listdir(path)
file_list = [ os.path.join(path,f) for f in file_list ]
return file_list
start = time.time()
files = eachfile('E:\采集文章\养生保健')
for i in files:
if '.txt' in i:
with open(i, encoding='gb18030') as f:
content = f.read()
print(i)
print(content)
end = time.time()
print(f'运行总耗时:{end-start:.2f}秒')
异步代码: 限制了并发500(打开文件太多会报错,windows系统默认是500多)
import asyncio
import aiofiles
import os, time
def eachfile(path):
file_list = os.listdir(path)
file_list = [ os.path.join(path,f) for f in file_list ]
return file_list
async def read_file(path):
if '.txt' in path:
async with sem:
async with aiofiles.open(path, encoding='gb18030') as f:
text = await f.read()
print(text)
async def main():
file_list = eachfile('E:\采集文章\养生保健')
tasks = [
asyncio.create_task(read_file(file_name)) for file_name in file_list
]
await asyncio.wait(tasks)
if __name__ == '__main__':
sem = asyncio.Semaphore(500)
start = time.time()
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
end = time.time()
print(f'运行总耗时:{end-start:.2f}秒')
多线程:
import os
import time
from concurrent.futures import ThreadPoolExecutor
def eachfile(path):
file_list = os.listdir(path)
file_list = [ os.path.join(path,f) for f in file_list ]
return file_list
start = time.time()
def read_file(file):
if '.txt' in file:
with open(file, encoding='gb18030') as f:
content = f.read()
print(file)
print(content)
with ThreadPoolExecutor(max_workers=100) as pool:
files = eachfile('E:\采集文章\养生保健')
pool.map(read_file, files)
end = time.time()
print(f'运行总耗时:{end-start:.2f}秒')
每个程序跑两次:
同步: 第一次耗时:98.08秒 , 第二次96.90秒
多线程: 第一次耗时:85.98秒, 第二次83.58秒
异步: 第一次耗时:109.96秒, 第二次:111.18秒
额 好像和想象的不太一样 异步反而耗时更长
网上查了下原因:
硬盘读取一个文件是最快的, 同时多读几个文件, 要在多个磁盘块中反复切换, 反而慢.
读文件和网络通讯不一样, 网络请求是在发送后, 需要等待, 这个时候可以使用协程提升并发数量.
硬盘不行.
aiofiles 库 存在的意义是什么,也许aiofiles 就是希望等待磁盘IO读取的时候,去做网络请求之类的操作。而不是我想的这种多个文件并发读取
下一篇:那些让你陷入时间黑洞的习惯
发表评论