我的 Python 代码将数百万个 ID 存储在各种数据结构中,以实现一个经典算法。运行时间还不错,但内存占用却很糟糕。
这些 id 是int
s。我猜想,由于 Python 的 int 类型起始于 28 个字节,并且会不断增长,因此代价非常大。由于它们只是不透明的 id,而不是真正的数学对象,所以我只用 4 个字节就可以了。
有没有一种方法可以在 Python 中存储 ID,而不用占用全部 28 个字节?例如,我是否需要将它们同时作为字典的键和值?
注意:像 BumPy 这样的常见解决方案在这里不起作用,因为它不是一个连续的数组。它是将键和值放入一个字典中,或者放入字典的字典中,等等。
我也乐意接受其他对 int 占用内存较少的 Python 解释器。
您的用例是将 ID 存储为字典的键和值。但是,由于字典的键和值必须是 Python 对象,因此必须为每个键和值分配一个对象头以及一个来自字典的指针。
为了能够真正以 4 个字节存储键和值,您必须实现一个自定义哈希表,
array.array
为键和值分配一个 32 位整数。由于 ID 通常不会是 0 或 2**32-1,因此您可以将它们分别用作空槽和已删除槽的标记。以下是线性探测的示例实现:
因此
pympler.asizeof
,使用递归测量对象的内存占用量,您可以看到内存节省高达 90%:请注意,在某些平台上,类型代码
'L'
会导致array.array
项目大小为 8 个字节而不是 4 个字节,在这种情况下您应该使用类型代码'I'
。