【发布时间】:2020-06-14 15:01:12
【问题描述】:
我是 Python 和并行执行和异步的新手。我做错了吗?我的代码运行速度较慢(或最多等于)以传统方式运行脚本所需的时间,没有异步。
import asyncio, os, time, pandas as pd
start_time = time.time()
async def main():
coroutines = list()
for root, dirs, files in os.walk('.', topdown=True):
for file in files:
coroutines.append(cleaner(file))
await asyncio.gather(*coroutines)
async def cleaner(file):
df = pd.read_csv(file, sep='\n', header=None, engine='python', quoting=3)
df = df[0].str.strip(' \t"').str.split('[,|;: \t]+', 1, expand=True).rename(columns={0: 'email', 1: 'data'})
df[['email', 'data']].to_csv('x1', sep=':', index=False, header=False, mode='a', compression='gzip')
asyncio.run(main())
print("--- %s seconds ---" % (time.time() - start_time))
【问题讨论】:
-
cleaner是否同步读/写文件系统?如果一个线程中的处理重叠等待另一个线程中的 I/O,则运行并行清理器而不是 asyncio 可能确实更快。如果您正在执行释放 GIL 并允许真正并行性的 pandas 操作,它会更快。 -
asyncio 可能不会比多线程应用程序快,只要它们中的任何一个有足够的工作来消耗整个 cpu。 asyncio 的优点是它不必锁定共享数据以及随之而来的所有问题。
-
确实...清洁器确实写入了多个文件。因此,输出目的地在各种协程之间共享。你对德莱尼有什么建议?
-
假设每个文件的处理独立于其他文件,这是
multiprocessing.Pool的理想选择,甚至可以将cleaner拉入单独的python 文件并使用subprocess运行它。我将发布一个示例。 -
您的代码无法更新,因为概念存在缺陷。仅当您有多个“等待”某个事件或资源的任务并且一个任务等待另一个任务时,Asyncio 才具有性能优势。您的代码必须具有利用这一点的可等待对象。声明一个函数“await def”不会带来任何好处,除非它包含一个“await”语句,并且await语句确实有一些它必须等待的东西。
标签: python python-asyncio