Python:减少字典的内存使用

2024-01-21

我正在尝试将几个文件加载到内存中。这些文件具有以下 3 种格式之一:

  • 字符串 TAB 整型
  • 字符串 TAB 浮点数
  • int TAB 浮点数。

事实上,它们是 ngram 静态文件,以防这有助于解决问题。例如:

i_love TAB 10
love_you TAB 12

目前,我现在正在做的伪代码是

loadData(file):
     data = {}
     for line in file:
        first, second = line.split('\t')
        data[first] = int(second) #or float(second)

     return data

令我惊讶的是,虽然磁盘中文件的总大小约为 21 mb,但加载到内存中时,该进程需要 120 - 180 mb 的内存! (整个Python应用程序不会将任何其他数据加载到内存中)。

文件数量不到10个,大部分都会稳定在50-80k行左右,除了一个文件目前有数百万行。

所以我想请求一种技术/数据结构来减少内存消耗:

  • 对于压缩技术有什么建议吗?
  • 如果我仍然使用dict,有什么办法可以减少内存吗?是否可以像 Java 中那样为 Python 字典设置“负载因子”?
  • 如果您有其他一些数据结构,我也愿意牺牲一些速度来减少内存。然而,这是一个时间敏感的应用程序,因此一旦用户输入查询,我认为花费超过几秒钟的时间来返回结果是不太合理的。对此,我仍然对谷歌能够如此快地完成谷歌翻译感到惊讶:他们一定使用了很多技术+大量服务器的能力?

非常感谢。我期待您的建议。


我无法提供有助于改善内存占用的完整策略,但我相信这可能有助于分析到底是什么占用了这么多内存。

如果你看一下Python实现字典(这是哈希表的相对直接的实现),以及内置字符串和整数数据类型的实现,例如here https://svn.python.org/projects/python/trunk/Include/(特别是 object.h、intobject.h、stringobject.h 和 dictobject.h,以及 ../Objects 中相应的 *.c 文件),您可以以一定的精度计算预期的空间需求:

  1. An integer是一个固定大小的对象,即它包含引用计数、类型指针和实际整数,通常总计至少 12 个字节在 32 位系统上和24 bytes在 64 位系统上,不考虑可能因对齐而丢失的额外空间。

  2. A string对象是可变大小的,这意味着它包含

  • 引用计数

  • 类型指针

  • 尺寸信息

  • 惰性计算哈希码的空间

  • 状态信息(例如用于interned字符串)

  • 指向动态内容的指针

    总共至少 24 字节在 32 位或60 bytes在 64 位上,不包括字符串本身的空间。

  1. The 字典本身由多个桶组成,每个桶包含
  • 当前存储的对象的哈希码(由于使用的冲突解决策略,无法从存储桶的位置预测)

  • 指向关键对象的指针

  • 指向值对象的指针

    总共至少 12 个字节在 32 位和24 bytes在 64 位上。

  1. 字典开头是8个空桶 and is 通过加倍调整大小达到其容量时的条目数。

我进行了测试包含 46,461 个唯一字符串(连接字符串大小为 337,670 字节)的列表,每个字符串都与一个整数关联 — 类似于您在 32 位计算机上的设置。根据上面的计算,我预计最小内存占用为

  • 字符串/整数组合 46,461 * (24+12) 字节 = 1.6 MB
  • 337,670 = 0.3 MB 字符串内容
  • 哈希桶 65,536 * 12 字节 = 1.6 MB(调整大小 13 次后)

总共 2.65 MB。 (对于 64 位系统,相应的计算结果为 5.5 MB。)

当Python解释器空闲运行时,其占用空间根据ps-工具为 4.6 MB。因此创建字典后预计总内存消耗约为 4.6 + 2.65 =7.25 MB. The 真实的内存占用(根据ps)在我的测试中是7.6 MB.我猜额外的约。 Python 的内存分配策略(对于内存区域等)产生的开销消耗了 0.35 MB

当然现在很多人会指出我使用ps测量内存占用量是不准确的,并且我对 32 位和 64 位系统上指针类型和整数大小的假设在许多特定系统上可能是错误的。的确。

但是,尽管如此,主要结论我相信,是这些:

  • 蟒蛇字典实现消耗惊人small内存量
  • 但很多人占用的空间int和(特别是)字符串对象,对于引用计数、预先计算的哈希码等,比您一开始想象的要多
  • 几乎没有办法避免内存开销,只要你使用 Python 并希望将字符串和整数表示为单独的对象 - 至少我不知道如何做到这一点
  • 寻找(或自己实现)可能是值得的Python-C 扩展它实现了一个将键和值存储为 C 指针(而不是 Python 对象)的哈希。我不知道这是否存在;但我相信这是可以做到的,并且可以将内存占用减少一半以上。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python:减少字典的内存使用 的相关文章

随机推荐

  • 如何在 MySQL innoDB 中重建索引并更新统计信息?

    我有使用 MS SQL 服务器的经验 它是可能且有用的 and 重建索引 https msdn microsoft com en us library ms189858 aspx 我在MySQL innoDB中找不到这样的选项 有这样的选项
  • CRAN 提交 - R CMD 检查警告 - 使用编译标志

    我正在尝试将我的第一个包裹提交至CRAN在我的机器上 我在运行时收到以下警告R CMD check via RStudio checking compilation flags used WARNING Compilation used t
  • C# NetCDF 库

    我目前正在从事 或至少正在计划 几个需要处理大量重复数据的项目 这种数据在电子表格或数据库中运行良好 但在 XML 中却很糟糕 NetCDF 似乎是一个不错的文件格式选择 但是 我的工作是使用 C 进行的 并且没有可用的 官方 NetCDF
  • 我可以从 Eclipse 视图中删除重复的运行配置吗?

    我有 Maven 父项目和孩子 当我去运行 gt 运行配置 in Java应用程序我两次看到很少的启动器 唯一的区别是路径Common选项卡 部分另存为 共享文件 我什至无法在不重命名第二个的情况下重命名其中一个 有没有办法至少隐藏两个同名
  • 具有可选参数的方法

    有没有一种方法可以使方法可以接受参数 但也可以在没有参数的情况下调用 在这种情况下 参数被视为nil像下面这样 some func variable some func def some func variable nil end
  • AngularJS 主页的多个 ng-views

    好吧 我是 Angluar 的新手 刚刚开始使用 ngRoute 和 ngView 指令 我遇到了一些对我来说是问题的问题 但我怀疑这只是一个问题 因为我缺乏 Angluar 的经验 我的 index html 页面上有以下标记 简化 di
  • Mercurial MSSCCAPI 提供商?

    有人知道 Mercurial 的 MSSCCAPI 提供商吗 我想使用 PowerBuilder 尝试 Kiln Mercurial 但 PowerBuilder IDE 只识别 MSSCCAPI 提供程序 即not与 MS SCC Pac
  • Microsoft Edge 请求后退/前进按钮上的新页面

    单击后退和前进按钮时 最新版本的 Microsoft Edge 浏览器 41 162 会请求新页面 我在多个平台上测试了多个浏览器 只有 Edge 表现出这种行为 这是一个测试页 http www easynotecards com sta
  • aws sagemaker模型训练中是否有某种持久的本地存储?

    我用aws sagemaker做了一些实验 从S3下载大数据集的时间是非常有问题的 特别是当模型仍处于开发阶段 并且你想要某种相对较快的初始反馈时 是否有某种本地存储或其他方式来加快速度 EDIT我指的是批量训练服务 它允许您以 Docke
  • 为什么 Flask 会话的值必须是 JSON 可序列化的?

    我正在尝试在 Flask 应用程序中为用户会话实例化一个基本模型实例 我对我的类必须是 JSON 可序列化的要求感到措手不及 我认为会话字典只是存储会话信息的任意构造 但听起来它的使用有更多限制 其中之一显然是 JSON 可序列化的值 还有
  • 可继承的版本 Maven 插件规则

    跑步时mvn versions display dependency updates为了版本 Maven 插件 https www mojohaus org versions maven plugin 我看到很多这样的事情 INFO org
  • 角度分量的类型

    我可以将角度组件类称为类型吗 我看到 Ionic 的用途any对于组件 在 Typescript 中是否可以声明一个仅需要组件类的参数类型 我看到了这个问题 但组件在构造函数中没有任何共同点 将类作为参数传递会导致 不可更新 错误 http
  • 如何将消息从后台服务发布到 UI 片段?

    我有一个问题EventBus来自绿色机器人 我试图从我的同步适配器的后台服务发布一个事件 并将其捕获在一个片段中以更新 UI 问题是 当我尝试从同步适配器发布事件时 我在调试日志中收到以下内容 No subscribers register
  • R闪亮:如何将本地图像放入闪亮的表中

    如果图像存储在我的机器上 我似乎无法在表格中显示图像 如果图像由 URL 指定 我可以让它工作 但我不知道有什么简单的方法来 提供 图像 以便可以通过 URL 找到它 而不是仅使用图像文件名并放置文件与 ui R 和 server R 位于
  • C++ std::filesystem::filesystem_error 试图读取系统卷信息等异常

    我正在尝试解决在尝试递归遍历根驱动器中的所有文件 如 C D 等 时引发的异常 我在 Mingw64 上使用 GCC 编译器版本 9 3 0 尝试读取系统卷信息时出现 std filesystem filesystem error 示例输出
  • CSS 过渡表格行高

    我有一个 CSS 表 所有行的高度相同 但当用户单击其中一行时 所选行应占据整个表格高度 其余行应逐渐消失 我通过简单的设置就可以工作display none在所有其他行上 但我想做一些过渡 我尝试过设置max height到 100 然后
  • 如何使用boto3通过另一个帐户的SQS订阅一个帐户的SNS主题?

    我正在尝试在一个帐户中创建一个 SNS 主题并将其附加到配置规则 我有 3 个这样的帐户 并且想在每个帐户中创建 SNS 主题 现在我想通过第四个帐户的SQS订阅3个不同帐户的所有3个主题 我可以手动完成 有人可以告诉我如何通过 boto3
  • google-apps-script 更改列格式

    需要格式化列 c e 和其他一些列 以使用以下格式显示日期 2014 年 7 月 4 日 不知道该怎么做 谷歌脚本新手 要使用 Apps 脚本执行此操作 您可以使用设置数字格式 数字格式 https developers google co
  • SSL 是如何工作的?

    我知道这不是一个具体的问题 但我阅读了这个主题大约一个小时 但找不到任何有关它的基本信息 SSL 是如何工作的 什么是私钥和公钥 为什么必须在公司购买证书以及自己签署证书有什么区别 到底什么是这样的证书 我读过几个网站 维基百科信息 Sta
  • Python:减少字典的内存使用

    我正在尝试将几个文件加载到内存中 这些文件具有以下 3 种格式之一 字符串 TAB 整型 字符串 TAB 浮点数 int TAB 浮点数 事实上 它们是 ngram 静态文件 以防这有助于解决问题 例如 i love TAB 10 love