为什么异步读取文件(使用 aiofile)比同步读取文件慢这么多(15 倍)?

问题描述 投票:0回答:0

我正在试验 mit 命名管道和 async 方法,有点惊讶,我创建的文件的读取速度似乎很慢。

正如this question所暗示的那样,这种效果不仅限于下面示例中的命名管道,还适用于“普通”文件。由于我的最终目标是阅读那些命名管道,因此我更愿意保留下面的示例。

所以这是我最初想出的:

import sys, os
from asyncio import create_subprocess_exec, gather, run
from asyncio.subprocess import DEVNULL
from aiofile import async_open

async def read_strace(namedpipe):
    with open("async.log", "w") as outfp:
        async with async_open(namedpipe, "r") as npfp:
            async for line in npfp:
                outfp.write(line)

async def main(cmd):
    try:
        myfifo = os.mkfifo('myfifo', 0o600)
        process = await create_subprocess_exec(
            "strace", "-o", "myfifo", *cmd, 
            stdout=DEVNULL, stderr=DEVNULL)
        await gather(read_strace("myfifo"), process.wait())
    finally:
        os.unlink("myfifo")

run(main(sys.argv[1:]))

您可以像 ./sync_program.py <CMD> 一样运行它,例如./sync_program.py find .

这个使用默认 Popen 并读取 strace 写入 myfifo 的内容:

from subprocess import Popen, DEVNULL
import sys, os

def read_strace(namedpipe):
    with open("sync.log", "w") as outfp:
        with open(namedpipe, "r") as npfp:
            for line in npfp:
                outfp.write(line)
   
def main(cmd):
    try:
        myfifo = os.mkfifo('myfifo', 0o600)
        process = Popen(
            ["strace", "-o", "myfifo", *cmd],
            stdout=DEVNULL, stderr=DEVNULL)
        read_strace("myfifo"),
    finally:
        os.unlink("myfifo")

main(sys.argv[1:])

time 运行两个程序表明异步程序慢了大约 15 倍:

$ time ./async_program.py  find .   
poetry run ./async_program.py find .  4.06s user 4.75s system 100% cpu 8.727 total
$ time ./sync_program.py find .
poetry run ./sync_program.py find .  0.27s user 0.07s system 76% cpu 0.438 total

链接的问题表明 aiofile 以某种方式缓慢,但 15 倍?我很确定我仍然通过使用额外的线程并写入队列来接近同步方法,但不可否认我还没有尝试过。

是否有推荐的异步读取文件的方法——甚至可能是一种更专用于命名管道的方法,因为我在给定的示例中使用了命名管道?

python asynchronous python-asyncio named-pipes python-aiofiles
© www.soinside.com 2019 - 2024. All rights reserved.