c# - 当许多键的值相同时减少数据内存 C#
问题描述
我有很多以下文本形式的数据:
4c5c,6c4h,486,30
4c5c,6c5h,486,30
4c5c,6c6h,458,0
4c5c,6c7h,648,9
4c5c,6c8h,648,9
3sTs,QsKs,182,0
3sTs,QsAs,182,0
3sTs,KsAs,743,0
3sJs,4s5s,495,0
3sJs,4s6s,625,0
3sJs,4s7s,739,0
3sJs,4s8s,739,0
3sJs,4s9s,739,0
3sJs,4sTs,739,0
3sJs,4sQs,182,0
3sJs,4sKs,739,0
3sJs,4sAs,625,0
3sJs,5s6s,625,0
3sJs,5s7s,739,0
3sJs,5s8s,739,0
在每一行中,前 2 个术语代表一个键,后 2 个术语代表值。例如 KEY: 3sJs,5s8s VALUE: 739,0
我有超过 140 亿条这样的行,并且一直将它们存储在字典中以便快速访问。这是有问题的,因为大约 250GB 的文本数据在存储在字典中时需要大量内存。但是,我注意到多个键的许多值是相同的。是否有一些替代字典的方法,我可以通过减少内存需求来存储这些数据,以利用重复许多值的事实?我以前没有使用过带有 C# 程序的数据库,但做了一点 postgres - sqlite 是我最好/唯一明智的选择,它会将我的应用程序大小减少到可管理的分发大小吗?
解决方案
我不确定你的价值是多少。你能把你的价值观编码到多小?我将假设您可以将它们打包成 4 个字节。
因此,您的密钥是描述 4 张扑克牌的文本字符串。因此,您可能的密钥空间最多为52^4 ~= 7.3e6
. 在所有可能的键中,哪个部分有值?离他们都近吗?
我不会使用文本字符串来表示您的密钥,而是为每张卡分配一个数字(0-51)。然后建立一个Int32
密钥=k1 + k2*52 + k3*(52^2) + k4*(52^3)
。
如果要为大多数键存储值,则不需要字典。您可以只使用一个长度数组52^4
。这样,您永远不需要为键本身分配任何内存。只需要4bytes * 52^4 ~= 28MB
ram。
然后将此数组存储在磁盘上,我会将其保存在 zip 存档中。如果您有许多相似的值,它应该可以很好地压缩。
您可能希望将此数据划分为多个部分,因此您不必将整个结构解压缩到内存中。但这取决于您希望在运行时如何使用这些数据。
推荐阅读
- javascript - 从 getJson 调用中获取响应文本
- python - 在 pytorch v1.0 Sequential 模块中使用 flatten
- reactjs - 使用 electron+react.js,组件在生产版本中不渲染
- flutter - 如何阻止flutter web在每次构建时覆盖我的index.html?
- laravel - 当我从我的 JS 客户端发送消息时,Laravel websocket 出现错误
- c++ - VS2019 上的 c++ 目录迭代器异常-已更改语言设置,还有什么要尝试的,2019 年是否已更改?
- python - 正则表达式动态查找模式 - Python
- java - 如何在 Android Studio 中自定义多个应用程序?
- angular - 如果使用 --env.uglify 编译,Nativescript Angular ui-calendar 不再存在
- css - 切断溢出图像而不溢出:隐藏