【发布时间】:2011-04-30 21:27:19
【问题描述】:
我需要一个内存高效的数据结构来存储大约一百万个键值对,其中键是大约 80 字节的字符串,值是大约 200 字节的字符串,键和值的总大小约为 280MB .我还需要通过键有效地查找值,最好是哈希映射。内存开销应尽可能少,例如对于 280MB 的有用数据,数据结构不应使用超过 300MB 的虚拟内存(包括malloc() 开销和其他所有内容)。使用模式如下:我们从一个空的数据结构开始,然后逐渐填充它,从不改变键,从不改变值的长度。另外,数据结构可以支持更改值的长度,但代价是 100% 的值开销(这意味着对于 x 值字节,x 字节可能会暂时浪费在未使用的缓冲区空间中)。
我需要一个纯 Python 模块,或者一个内置 Python 模块,或者一个最好带有 (C)Python 绑定的 C 实现。如果可以将整个数据结构序列化到磁盘并快速读取它,我会更喜欢。
为了证明这么小的开销是可能的,我用open addressing 创建了一个简单的设计,125 万个元素的哈希表包含指向 1MB 数据块的 4 字节指针,数据块包含密钥和值长度为base-128 varints。这种设计有一个重要的限制:它不允许在不浪费内存区域的情况下删除或更改对。根据我对 100 万个每个 280 字节的键值对的计算,开销小于 3.6%(10 080 000 字节)。上面的限制更加慷慨,它们允许 20 000 000 字节的开销。
我刚刚找到 http://www.pytables.org/ ,它提供了快速访问和内存高效的数据打包。我必须更仔细地检查它是否适合我的需要。
【问题讨论】:
-
是否考虑使用 sqlite 实现选项?
-
或东京内阁,或cdb,或?
-
"最好是哈希映射。内存开销应该尽可能小" 通常不兼容。哪个更重要?速度或大小。把它当作一个给定的,你永远不能同时拥有。
-
下面的许多答案,包括我的,都忽略了您对 C 实现的要求。也许你可以告诉我们为什么你需要 C?我假设您需要它来提高性能,并忽略了这一点,因为我们还不知道该区域缺少纯 Python 选项。如果还有其他需要 C 的原因,那么我们的答案当然是遥遥无期。
-
@Martijn:你的意思是
":memory:"SQLite 数据库吗?是的,这是一个有效的选择,但我不确定它是否足够紧密地打包数据。值得一试。
标签: python data-structures hash map memory-efficient