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