【发布时间】:2011-10-12 21:12:21
【问题描述】:
我用 Python 编写了一个工作程序,它基本上解析一批二进制文件,将数据提取到数据结构中。每个文件大约需要一秒钟的时间来解析,这意味着数千个文件需要几个小时。我已经成功实现了批处理解析方法的线程版本,线程数可调整。我用不同数量的线程在 100 个文件上测试了该方法,并为每次运行计时。以下是结果(0 个线程指的是我原来的预线程代码,1 个线程指的是新版本的运行,并产生了一个线程)。
0 threads: 83.842 seconds
1 threads: 78.777 seconds
2 threads: 105.032 seconds
3 threads: 109.965 seconds
4 threads: 108.956 seconds
5 threads: 109.646 seconds
6 threads: 109.520 seconds
7 threads: 110.457 seconds
8 threads: 111.658 seconds
虽然与让主线程完成所有工作相比,生成线程会带来小幅性能提升,但实际上增加线程数会降低性能。我本来希望看到性能提高,至少多达四个线程(一个用于我机器的每个内核)。我知道线程有相关的开销,但我认为这对于个位数的线程来说并不重要。
我听说过“全局解释器锁”,但是当我移动到四个线程时,我确实看到了相应数量的内核在工作——两个线程两个内核在解析期间显示活动,等等。
我还测试了一些不同版本的解析代码,看看我的程序是否是 IO 绑定的。似乎不是;仅仅读入文件花费的时间比例相对较小;处理文件几乎是全部。如果我不执行 IO 并处理文件的已读取版本,我添加第二个线程会损害性能,而第三个线程会稍微改善它。我只是想知道为什么我不能利用计算机的多核来加快速度。请发表任何问题或我可以澄清的方式。
【问题讨论】:
-
这里的 GIL 可能有问题。您可以查看多处理模块,作为线程模块的替代方案,因为它实现了真正的并发性,而 GIL 将阻止它进行线程化。
-
看看this。你已经遇到了唯一我讨厌 Python 的地方(好吧,反正是 CPython)。
-
多个核心会显示活动,但它只是在它们之间切换 - 一次只能运行一个 Python 线程。您需要多处理:docs.python.org/dev/library/multiprocessing
-
-
我将研究使用多处理;我正在运行 Python 2.4,所以我需要先升级,这就是我对线程感兴趣的原因。我认为多处理只是围绕线程/线程的更高级别的外壳。那么穿线有什么意义呢?而且我仍然不确定我是否理解为什么多个线程会减慢我的程序——这只是线程开销吗?
标签: python multithreading performance io