Python 如何优化简单代码的多进程速度

2023-07-17 18:35:40 +08:00
 JustBecause

写了一个程序,使用 PySide6 带有 GUI ,用来处理字幕的文本内容

因为要用到 CPU 处理,多线程和异步效果不佳,所以想做成多进程的形式处理,用的进程池来操作

pool = multiprocessing.Pool()
results = pool.map(analysisSubtitles, subtitles_list)
pool.close()
pool.join()

analysisSubtitles 是识别每个字幕每行内容并做替换。每个字幕文件处理时间 30-300ms 左右,但使用了多进程以后,无论拖入一个还是十个文件,都要至少 1.5s 起步才能处理完成

这是什么原因导致的,有没有办法优化?

百度谷歌必应和 GPT 都问过了,实在找不到问题原因

===

macOS 上我加了 multiprocessing.set_start_method("fork") 解决,基本在 0.5s 内就可以完成

但我也有在 windows 使用的需求,请问 windows 下如何优化才能减少执行时间?

感谢各位

1566 次点击
所在节点    Python
6 条回复
sordidclown
2023-07-18 07:58:30 +08:00
Python 新手,猜一下可能是任务太轻量了? Windows 上没有 `fork`,默认是 `spawn` 这种重量级的构建方式。鉴于 MacOS 上使用 `fork` 能降低执行时间。所以可能任务执行的时间还没有构建新进程的时间长,也就是“构建新进程”所占时间的比重较大。
我觉得如果要减少执行时间,又要多进程,你可以试着限制进程池的大小。或者说任务比较多的时候再开多进程,这样能有效减少构建新进程占用的时间。
PS:网上搜了点资料猜的,大佬们轻喷。
sordidclown
2023-07-18 08:05:40 +08:00
我再提供一个思路,比如说将“读写文件”和“实际处理处理”分离成两个函数,一个作为 IO 密集函数,一个作为 CPU 密集函数。IO 密集的部分使用线程或者协程处理,CPU 密集的部分采用多线程处理。这两部分可以使用管道或者队列通信。
JustBecause
2023-07-18 10:37:49 +08:00
@sordidclown #2
任务确实非常轻量,可以理解成 time.sleep(0.3)这样子,主要是执行的数量多
实际上拖放文件进窗口就开始执行了,这部分没有太多的操作
时间主要在 pool.map 这一步上,所以读写文件和实际处理分开大概没效果
试过把多进程执行的函数改成 time.sleep(0.3),但也要花 1.5s 以上处理
wuwukai007
2023-07-18 11:18:02 +08:00
开多个进程启动很慢的,做一个常驻进程池
JustBecause
2023-07-19 10:29:14 +08:00
@wuwukai007 #4
感谢 常驻进程池真能行
之前每次执行都执行一遍 pool = multiprocessing.Pool(),现在放到软件启动时创建,速度就正常了
runstone
2023-07-19 16:55:20 +08:00
concurrent.futures.ProcessPoolExecutor 作为进程池应该好一些吧。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/957506

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX