Deprecated: Using ${var} in strings is deprecated, use {$var} instead in /www/wwwroot/sengshao.com/zb_system/function/c_system_event.php on line 2059

Deprecated: Using ${var} in strings is deprecated, use {$var} instead in /www/wwwroot/sengshao.com/zb_system/function/c_system_event.php on line 2060

Deprecated: Return type of Config::current() should either be compatible with Iterator::current(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /www/wwwroot/sengshao.com/zb_system/function/lib/config.php on line 26

Deprecated: Return type of Config::next() should either be compatible with Iterator::next(): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /www/wwwroot/sengshao.com/zb_system/function/lib/config.php on line 36

Deprecated: Return type of Config::key() should either be compatible with Iterator::key(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /www/wwwroot/sengshao.com/zb_system/function/lib/config.php on line 31

Deprecated: Return type of Config::valid() should either be compatible with Iterator::valid(): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /www/wwwroot/sengshao.com/zb_system/function/lib/config.php on line 41

Deprecated: Return type of Config::rewind() should either be compatible with Iterator::rewind(): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /www/wwwroot/sengshao.com/zb_system/function/lib/config.php on line 17

Deprecated: Constant E_STRICT is deprecated in /www/wwwroot/sengshao.com/zb_system/function/c_system_debug.php on line 80

Deprecated: Constant E_STRICT is deprecated in /www/wwwroot/sengshao.com/zb_system/function/c_system_debug.php on line 80
python同步读取文件vs多线程读取vs异步读取文件aiofiles - 僧少博客
当前位置:首页 > 编程 > 正文

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,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读取的时候,去做网络请求之类的操作。而不是我想的这种多个文件并发读取

    

发表评论


Deprecated: Constant E_STRICT is deprecated in /www/wwwroot/sengshao.com/zb_system/function/c_system_debug.php on line 80