gpt4 book ai didi

python - 为什么protobuf的内存比python中的普通dict+list小?

转载 作者:行者123 更新时间:2023-12-03 18:33:34 25 4
gpt4 key购买 nike

我在嵌套的字典/列表中有大量的原始类型结构。结构相当复杂,并不重要。
如果我用 python 的内置类型( dict/list/float/int/str )表示它,则需要 1.1 GB,但如果我将它存储在 protobuf 中并将其加载到内存中它要小得多。总共约 250 MB。
我想知道这怎么可能。与某些外部库相比,python 中的内置类型效率低吗?
编辑:结构是从 json 文件加载的。所以对象之间没有内部引用

最佳答案

“简单”python 对象,例如 intfloat ,需要比 protobuf 使用的 C 对应项更多的内存.
让我们来个list Python 整数作为示例与整数数组进行比较,例如在 array.array 中(即 array.array('i', ...) )。array.array 的分析很简单:从 array.arrays 中丢弃一些开销-object,每个元素只需要 4 个字节(C 整数的大小)。
对于整数列表,情况完全不同:

  • 该列表不包含整数对象本身,而是指向对象的指针(8 64 位可执行文件的附加字节)
  • 即使是一个小的非零整数也至少需要 28字节(见 import sys; sys.getsizeof(1) 返回 28):引用计数需要 8 个字节,保存指向整数函数表的指针需要 8 个字节,整数值的大小需要 8 个字节(Python 的整数可以远大于2^32),并且至少有 4 个字节来保存整数值本身。
  • 还有一个overhead for memory management of 4.5 bytes .

  • 这意味着与可能的 4 个字节(如果我们使用 long long int,即 64 位整数,则为 8 个字节)相比,每个 Python 整数的成本高达 40.5 个字节。
    doubles 的数组相比,具有 Python 浮点数的列表的情况类似。 (即 array.array('d',...) ),每个元素只需要大约 8 个字节。但是对于列表,我们有:
  • 该列表不包含浮点对象本身,而是指向对象的指针(8 64 位可执行文件的附加字节)
  • float 对象需要 24字节(见 import sys; sys.getsizeof(1.0) 返回 24):引用计数需要 8 个字节,保存指向浮点函数表的指针需要 8 个字节,保存 double 需要 8 个字节。 -值(value)本身。
  • 因为 24 是 8 的倍数,所以内存管理的开销“仅”约为 0.5 个字节。

  • 这意味着 Python 浮点对象为 32.5 字节,而 C-double 为 8 字节。 protobuf在内部使用与 array.array 相同的数据表示形式因此需要更少的内存(如您所见,大约少 4-5 倍)。 numpy.array是数据类型的另一个示例,它保存原始 C 值,因此比列表需要更少的内存。

    如果不需要在字典中搜索,那么将键值对保存在列表中将比在字典中需要更少的内存,因为不必维护用于搜索的结构(这会增加一些内存成本) ) - 这也是导致 protobuf 内存占用更小的另一件事-数据。

    要回答您的其他问题:Python- dict 没有内置模块, 什么 array.array是 Python- list ,所以我借此机会厚颜无耻地为我的一个图书馆插了一个广告: cykhash .
    来自 cykhash 的集合和 map need less than 25% Python的- dict/ set内存,但速度差不多。

    关于python - 为什么protobuf的内存比python中的普通dict+list小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63439648/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com