Python 非常大的集合。如何避免内存不足异常?

标签 python python-2.7

我使用 Python 集合来存储唯一对象。每个对象都覆盖了 __hash____eq__

该集合包含近 200 000 个对象。该装置本身占用近 4 GB 的内存。 它在超过 5 GB 的机器上运行良好,但现在我需要在只有 3 GB 可用 RAM 的机器上运行脚本。

我用 C# 重写了一个脚本 - 实际上从同一源读取相同的数据,将其放入 CLR 模拟集 (HashSet) 中,而不是 4 GB,它占用了近 350 MB,而脚本执行速度相对同样(将近 40 秒)但我必须使用 Python。

问题 1:Python 是否有任何“磁盘持久化”设置或任何其他解决方法?我猜它只能在内存中存储 hash/eq 方法中使用的“关键”数据,其他所有内容都可以保存到磁盘。或者可能在 Python 中有其他解决方法来拥有一个唯一的对象集合,这些对象可能占用比系统可用内存更多的内存。

Q2:不太实际的问题:为什么 python set 为一个 set 占用这么多内存?

我在 64 位 Ubuntu 12.10 上使用标准 Python 2.7.3

谢谢。

更新一: 脚本的作用:

  1. 阅读大量半结构化 JSON 文档(每个 JSON 由序列化对象和与其相关的聚合对象集合组成)

  2. 解析每个 JSON 文档以从中检索主要对象和聚合集合中的对象。每个解析的对象都存储到一个集合中。 Set 仅用于存储唯一对象。首先,我使用了一个数据库,但数据库中的唯一约束工作速度较慢 x100-x1000。每个 JSON 文档都被解析为 1-8 种不同的对象类型。每个对象类型都存储在它自己的集合中,以便仅在内存中保存唯一的对象。

  3. 存储在集合中的所有数据都保存到具有唯一约束的关系数据库中。每个集合都存储在单独的数据库表中。

脚本的整体思路是获取非结构化数据,从 JSON 文档中的聚合对象集合中删除重复项,并将结构化数据存储到关系数据库。

更新 2:

2 delnan:我评论了所有代码行,添加到不同的集合中,使所有其他人员(获取数据、解析、迭代)保持相同——脚本占用的内存减少了 4 GB。

这意味着当将那些 200K 对象添加到集合中时 - 它们开始占用如此多的内存。该对象是来自 TMDB 的简单电影数据 - ID、流派列表、 Actor 、导演列表、许多其他电影细节以及可能来自维基百科的大型电影描述。

最佳答案

集合确实占用大量内存,但列表不会。

>>> from sys import getsizeof
>>> a = range(100)
>>> b = set(a)
>>> getsizeof(a)
872
>>> getsizeof(b)
8424
>>>

如果您使用集合的唯一原因是为了防止重复,我建议您改用列表。您可以通过在添加对象之前测试对象是否已在您的列表中来防止重复。它可能比使用集合的内置机制慢,但肯定会使用更少的内存。

关于Python 非常大的集合。如何避免内存不足异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15555728/

相关文章:

python - 如何获取多类别的所有混淆矩阵术语(TPR、FPR、TNR、FNR)?

python - 如何在 python 中找到 csv 文件的一列的平均值?

python - 重新组织Python字典中的输出数据

Python:基于键值长度的OrderedDictionary排序

python - 如何在python脚本中检查系统是否为FreeBSD?

c# - Python 到 C# 移植后的错误计算

python - 在 Python 中使用 GLUT/OpenGL 绘制文本

python - Django Admin 使用 nginx 端口 443 挂起

python - 查找pip包: pkg_resources specify custom target directory

python - 如何将列表中的项目设置为特定变量?