异步会在这里帮助我吗?

时间:2018-07-05 20:35:14

标签: python wxpython python-asyncio

我有一个使用wxpython4.0.3开发的小python应用程序,它执行以下相当简单的ETL类型任务:

  • 接受用户输入以选择包含多个目录的父目录 包含CSV文件(时间序列数据)的子目录。
  • 转换每个文件中的数据以符合格式 由第三方收件人要求,并将其写到新 文件。
  • 将每个新文件压缩到以原始文件命名的文件中 文件的父目录
  • 在用户的主动下,应用程序随后将zip文件通过FTP传输到 要加载到数据存储中的第三方。

该应用程序运行良好,但是处理数千个CSV文件所需的时间非常长,而且从我所知道的来看,大部分都是IO约束。

异步是追求合理的选择还是有人可以提出其他建议?我最初是作为CLI编写的,使用pypy可以显着提高性能,但是当我为其他人开发UI时,我不愿意将pypy与wxpython结合使用。

感谢您的指导。

2 个答案:

答案 0 :(得分:2)

如果通过使用PyPy而不是CPython看到了显着的加速,则表明您的代码可能不受I / O约束。这意味着使I / O异步不会有太大帮助。另外,这也将是额外的工作,因为您必须将所有占用大量CPU的任务重组为小块,这些小块可以反复await,以便它们不会阻塞其他任务。

因此,您可能要在此处使用多个过程。

最简单的解决方案是使用concurrent.futures.ProcessPoolExecutor:只需在执行程序上扔任务,它将在子进程上运行它们并返回Future

与使用asyncio不同,您根本不必更改这些任务。他们可以通过遍历csv模块来读取文件,将其全部处理成一个大块,甚至可以使用同步ftplib模块,而不必担心有人阻塞其他任何人。只需更改您的顶级代码。

但是,您可能需要考虑将代码分成在CPython中运行的wx GUI和在PyPy中通过subprocess运行的多处理引擎,然后分拆{{ 1}}在PyPy中也是如此。这将花费更多的工作,但是这意味着您将获得使用PyPy的CPU优势,经过充分测试的使用CPython的wx优势以及多处理的并行性。

要考虑的另一种选择是引入像NumPy或Pandas这样的库,它们可以做得较慢(无论是读取和处理CSV,还是对数千行进行某种元素计算,等等)。甚至可能释放GIL,这意味着您不需要多处理)。


如果您的代码确实是 的I / O绑定代码,并且主要绑定在FTP请求上,那么ProcessPoolExecutor会有所帮助。但这需要重写大量代码。您需要找到或编写一个asyncio驱动的FTP客户端库。而且,如果文件读取花费了您的大部分时间,那么将其转换为异步将更加艰巨。

还存在将asyncio事件循环与wx事件循环集成的问题。您可能可以在第二个线程中运行asyncio循环,但是您需要想出一种在主线程中的asyncio事件循环和{{ 1}}在后​​台线程中循环。或者,您可能能够驱动另一个循环(或者甚至可能有第三方库为您完成该循环)。但是,使用wx而不是asyncio这样的东西(或者有更好的第三方库来帮助)可能会容易得多。

但是,除非您需要大量的并发(除非您需要与之对话的数百个不同的FTP服务器,否则可能不需要),线程应该也可以正常工作,并且对代码的更改更少。只需使用concurrent.futures.ThreadPoolExecutor,几乎与上述使用twisted相同。

答案 1 :(得分:0)

是的,您可能会受益于使用异步库。由于您的大部分时间都花在等待IO上,因此编写良好的异步程序将利用该时间执行其他操作,而不会产生额外的线程/进程的开销。它将很好地扩展。