当前位置:首页 > 编程 > 正文

python同步读取文件vs多线程读取vs异步读取文件aiofiles

文件夹内采集了7w多篇txt文章 读取每篇文章内容比较耗时,所以想着有个异步库aiofiles  测试一下同步与异步效率的差别 

同步代码:

import os
import time

def eachfile(path):
    file_list = os.listdir(path)
    file_list = [ os.path.join(path,ffor f in file_list ]
    return file_list

start = time.time()

files = eachfile('E:\采集文章\养生保健')
for i in files:
    if '.txt' in i:
        with open(iencoding='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 ostime


def eachfile(path):
    file_list = os.listdir(path)
    file_list = [ os.path.join(path,ffor f in file_list ]
    return file_list

async def read_file(path):
    if '.txt' in path:
        async with sem:
            async with aiofiles.open(pathencoding='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,ffor f in file_list ]
    return file_list

start = time.time()

def read_file(file):
    if '.txt' in file:
        with open(fileencoding='gb18030'as f:
            content = f.read()
            print(file)
            print(content)
            
with ThreadPoolExecutor(max_workers=100as pool:
    files = eachfile('E:\采集文章\养生保健')
    pool.map(read_filefiles)


    
end = time.time()
print(f'运行总耗时:{end-start:.2f}秒')


每个程序跑两次:

同步: 第一次耗时:98.08秒 , 第二次96.90秒

多线程: 第一次耗时:85.98秒, 第二次83.58秒

异步: 第一次耗时:109.96秒, 第二次:111.18秒 


额 好像和想象的不太一样  异步反而耗时更长  


网上查了下原因:

硬盘读取一个文件是最快的, 同时多读几个文件, 要在多个磁盘块中反复切换, 反而慢.

读文件和网络通讯不一样, 网络请求是在发送后, 需要等待, 这个时候可以使用协程提升并发数量.
硬盘不行.

aiofiles 库 存在的意义是什么,也许aiofiles 就是希望等待磁盘IO读取的时候,去做网络请求之类的操作。而不是我想的这种多个文件并发读取

    

发表评论