为了账号安全,请及时绑定邮箱和手机立即绑定

2000 万个键值对的磁盘空间效率最高的内存映射字典,速度不是太大问题

2000 万个键值对的磁盘空间效率最高的内存映射字典,速度不是太大问题

HUWWW 2022-05-11 15:50:49
我有大约 2000 万个键值对。我需要创建两个字典。第一个字典:值是整数,从 0 到 2000 万。键是长度为 40 个字符的字符串,例如 '36ae99662ec931a3c20cffdecb39b69a8f7f23fd'。第二本词典:第一本词典的逆向。键是整数,从 0 到 2000 万。这些值是长度为 40 个字符的字符串,例如 '36ae99662ec931a3c20cffdecb39b69a8f7f23fd'。我认为对于第二个字典,有更多选择,因为索引可以用作键。对于第二个选项,sqlite3 看起来很有希望。查找速度不是太重要,1 秒查找应该没问题。主要担心的是我没有太多空间来存储字典。至于我对第一类字典的最佳猜测,来自this SO post*大* python 字典,具有持久性存储,用于快速查找看起来 dbm 对于第一种类型的字典来说是一个不错的解决方案,因为所有的键和值都存储为字节,尽管答案是在 7 年前的 2012 年给出的。我不确定它今天是否是一个不错的解决方案。
查看完整描述

2 回答

?
猛跑小猪

TA贡献1858条经验 获得超8个赞

字符串看起来是十六进制的。在这种情况下,您可以首先使用binascii.unhexlify将它们转换为二进制字符串。这样就节省了 50% 的空间。


In [2]: import binascii


In [3]: binascii.unhexlify('36ae99662ec931a3c20cffdecb39b69a8f7f23fd')

Out[3]: b'6\xae\x99f.\xc91\xa3\xc2\x0c\xff\xde\xcb9\xb6\x9a\x8f\x7f#\xfd'


In [4]: len(binascii.unhexlify('36ae99662ec931a3c20cffdecb39b69a8f7f23fd'))

Out[4]: 20

2000 万个键/值对对于现代计算机来说并不算多。查看纯数据的大小(字符串为 20 个字节,整数为 4 个字节),我们谈论的是大约半 GB。


In [5]: 20e6 * (20 + 4) / 1e9

Out[5]: 0.48

最节省空间的方法是只创建一个键/值对数组,按键排序。因为我们知道每对都是 24 字节,所以在映射文件中访问它们是微不足道的;你可以只使用切片。我会使用二进制搜索进行查找。


这没有存储开销。但是插入一个值将是低效的。


查看完整回答
反对 回复 2022-05-11
?
绝地无双

TA贡献1946条经验 获得超4个赞

考虑到您的第二个字典与第一个字典相反,我认为您可能想要使用单表数据库。您可以有一个主键,然后在字符串上建立一个索引,以便快速查找。像 sqlite 这样的东西是有道理的。

你正在处理什么大小的内存?它可能仍然在 python 的内存中,但这一切都取决于你有多少内存。


查看完整回答
反对 回复 2022-05-11
  • 2 回答
  • 0 关注
  • 143 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号