【发布时间】:2019-02-07 13:54:55
【问题描述】:
我有一个 Python 脚本,它计算一个非常大的文本中每个 k 长子字符串的出现次数。在存储和删除子字符串之后,它就是这样做的:
counts = {}
for s in all_substrings:
counts[s] = full_text.count(s)
我惊讶地发现这个脚本平均只使用了 4% 的 CPU。我有一个 4 核 8 线程 CPU,但没有一个内核的使用率超过个位数。我原以为脚本会 100% 使用一个内核,因为它不执行 IO。
为什么它使用这么少的计算能力,我该如何改进?
【问题讨论】:
-
如果文本存储在内存中,然后查看分页/交换。
-
计算绑定的纯 Python 代码的执行通过全局解释器锁 (GIL) 限制在单个线程中。如果您希望您的代码是并行的,您必须自己编写(并且有很多选择可以这样做)。在您的具体情况下,我会调查
collections.Counter()。 -
@cdarke 我有 16GB RAM,其中一半是免费的,系统交换我的脚本不断处理的数据是否有意义?
-
@norok2 它甚至没有使用 5% 的单核,所以我认为并行化不是解决方案。
-
与您的问题没有直接关系,但我怀疑收集子字符串列表并使用它们中的每一个调用
count可能比仅编写文本所有切片的计数器慢,即@ 987654325@。如果子字符串中的重复项很少,那么您当前的方法是 O(len(full_text)^2)。循环切片是 O(len(full_text))。