我已经用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
尽管生成线程比使主线程完成所有工作会带来较小的性能提升,但是增加线程数实际上会降低性能。我本来希望看到性能提高,至少可以达到四个线程(我的机器的每个内核一个)。我知道线程有相关的开销,但是我认为线程数没有多大影响。
我听说过“全局解释器锁定”,但是当我向上移动四个线程时,我确实看到了相应数量的内核在工作-具有两个线程,两个内核在解析期间显示 Activity ,依此类推。
我还测试了一些不同版本的解析代码,以查看我的程序是否受IO限制。似乎并非如此;仅读取文件所需的时间就相对较少;处理文件几乎是全部。如果不执行IO并处理文件的已读取版本,则添加第二个线程会损害性能,而第三个线程会稍微改善性能。我只是想知道为什么我不能利用计算机的多核来加快处理速度。请发布任何问题或我可以澄清的方式。
最佳答案
令人遗憾的是,这主要是由于全局解释器锁(GIL)导致的CPython中的情况。受CPU约束的Python代码根本无法跨线程扩展(另一方面,受I/O约束的代码可能会在一定程度上扩展)。
大卫·比兹利(David Beazley)撰写了一本内容丰富的presentation,他在其中讨论了有关GIL的一些问题。该视频可以在here中找到(感谢@Ikke!)
我的建议是使用 multiprocessing
模块而不是多个线程。
关于python - Python代码的性能随线程而降低,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6821477/