Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 异步版本的运行速度比非异步版本慢_Python_Asynchronous_Python Asyncio_Python Aiofiles - Fatal编程技术网

Python 异步版本的运行速度比非异步版本慢

Python 异步版本的运行速度比非异步版本慢,python,asynchronous,python-asyncio,python-aiofiles,Python,Asynchronous,Python Asyncio,Python Aiofiles,我的程序执行以下操作: 获取.txt文件的文件夹 对于每个文件: 2.1。读文件 2.2将内容排序为列表,并将列表推送到主列表 我这样做没有任何异步/等待,这些是时间统计数据 real 0m0.036s user 0m0.018s sys 0m0.009s 使用下面的异步/等待代码,我得到 real 0m0.144s user 0m0.116s sys 0m0.029s 给定的用例表明我不正确地使用了aysncio 有人知道我做错了什么吗 im

我的程序执行以下操作:

  • 获取.txt文件的文件夹
  • 对于每个文件:

    2.1。读文件

    2.2将内容排序为列表,并将列表推送到主列表

  • 我这样做没有任何异步/等待,这些是时间统计数据

    real    0m0.036s
    
    user    0m0.018s
    
    sys     0m0.009s
    
    使用下面的异步/等待代码,我得到

    real    0m0.144s
    
    user    0m0.116s
    
    sys     0m0.029s
    
    给定的用例表明我不正确地使用了aysncio

    有人知道我做错了什么吗

    import asyncio
    import aiofiles
    import os
    
    directory = "/tmp"
    listOfLists = list()
    
    async def sortingFiles(numbersInList):
        numbersInList.sort()
    
    async def awaitProcessFiles(filename,numbersInList):
        await readFromFile(filename,numbersInList)
        await sortingFiles(numbersInList)
        await appendToList(numbersInList)
    
    
    async def readFromFile(filename,numbersInList):
        async with aiofiles.open(directory+"/"+filename, 'r') as fin:
            async for line in fin:
                return numbersInList.append(int(line.strip("\n"),10))            
        fin.close()    
    
    async def appendToList(numbersInList):
        listOfLists.append(numbersInList)
    
    async def main():
        tasks=[]
        for filename in os.listdir(directory):
            if filename.endswith(".txt"):  
                numbersInList =list()
                task=asyncio.ensure_future(awaitProcessFiles(filename,numbersInList))
                tasks.append(task)
        await asyncio.gather(*tasks)   
    
    if __name__== "__main__":
        asyncio.run(main())
    
    分析信息:

            151822 function calls (151048 primitive calls) in 0.239 seconds
    
       Ordered by: internal time
    
       ncalls  tottime  percall  cumtime  percall filename:lineno(function)
           11    0.050    0.005    0.050    0.005 {built-in method _imp.create_dynamic}
           57    0.022    0.000    0.022    0.000 {method 'read' of '_io.BufferedReader' objects}
           57    0.018    0.000    0.018    0.000 {built-in method io.open_code}
          267    0.012    0.000    0.012    0.000 {method 'control' of 'select.kqueue' objects}
           57    0.009    0.000    0.009    0.000 {built-in method marshal.loads}
          273    0.009    0.000    0.009    0.000 {method 'recv' of '_socket.socket' objects}
          265    0.005    0.000    0.098    0.000 base_events.py:1780(_run_once)
          313    0.004    0.000    0.004    0.000 {built-in method posix.stat}
          122    0.004    0.000    0.004    0.000 {method 'acquire' of '_thread.lock' objects}
      203/202    0.003    0.000    0.011    0.000 {built-in method builtins.__build_class__}
         1030    0.003    0.000    0.015    0.000 thread.py:158(submit)
         1030    0.003    0.000    0.009    0.000 futures.py:338(_chain_future)
         7473    0.003    0.000    0.003    0.000 {built-in method builtins.hasattr}
         1030    0.002    0.000    0.017    0.000 futures.py:318(_copy_future_state)
           36    0.002    0.000    0.002    0.000 {built-in method posix.getcwd}
         3218    0.002    0.000    0.077    0.000 {method 'run' of 'Context' objects}
         6196    0.002    0.000    0.003    0.000 threading.py:246(__enter__)
         3218    0.002    0.000    0.078    0.000 events.py:79(_run)
         6192    0.002    0.000    0.004    0.000 base_futures.py:13(isfuture)
         1047    0.002    0.000    0.002    0.000 threading.py:222(__init__)
    

    制作一些测试文件

    import random, os
    path = <directory name here>
    nlines = range(1000)
    nfiles = range(1,101)
    for n in nfiles:
        fname = f'{n}.txt'
        with open(os.path.join(path,fname),'w') as f:
            for _ in nlines:
                q = f.write(f'{random.randrange(1,10000)}\n')
    
    随机导入,操作系统
    路径=
    nlines=范围(1000)
    n文件=范围(1101)
    对于n英寸文件:
    fname=f'{n}.txt'
    将open(os.path.join(path,fname),'w')作为f:
    对于uu-in-nline:
    q=f.write(f'{random.randrange(110000)}\n')
    
    异步IO对于本地文件没有什么意义。这就是为什么,即使是python标准库也没有它们

    async for line in fin:
    
    考虑上面这一行。对于每一行读取,事件循环都会暂停co例程,并执行其他一些co例程。这意味着cpu缓存中的以下文件行将被丢弃,以便为下一个协同例程腾出空间。(尽管如此,它们仍将在RAM中)

    什么时候应该使用所有文件?

    假设您已经在程序中使用了异步代码,并且偶尔需要进行一些文件处理。如果文件处理是在同一个事件循环中完成的,那么所有其他co例程都将被阻止。在这种情况下,您可以使用aiofiles,也可以在不同的执行器中进行处理


    如果程序所做的只是读取文件。按顺序执行这些操作会更快,以便充分利用缓存。从一个文件跳到另一个文件类似于线程上下文切换,应该会使其变慢。

    如果代码受cpu限制(也就是说,大部分时间都花在排序上),那么这个结果是合理的,因为异步会增加开销。你有没有分析过要花多少时间?有多少文件?文件中有多少行(您正在排序行?)?似乎您应该只需要async来打开和读取文件。排序和累积可以在与打开和读取相同的协同程序中完成。我可能会用
    concurrent.futures
    来做这件事。目前用10个文件测试,每个文件大约有1000行。@PiRocks在描述中添加了分析信息。我认为执行异步的全部目的是执行非阻塞I/O。我还将异步从排序和添加到列表中删除。尽管如此,性能还是不如非异步的1.1000行文件大;管理异步代码的开销可能比交错处理和IO所节省的开销更大。Asyncio用于IO绑定进程。在这里,我们要做一些列表操作,比如追加和排序。除非我弄错了,否则这些都不是IO绑定的进程。考虑到这一点,为这些操作使用协同程序并没有真正意义。