use*_*014 7 python json protocol-buffers python-3.x
我在嵌套的 dict/list 中有一个大型的原始类型结构。结构相当复杂,并不重要。
如果我用 python 的内置类型 ( dict/ list/ float/ int/ str) 表示它需要 1.1 GB,但如果我将它存储protobuf并加载到内存中,它会小得多。总共约 250 MB。
我想知道这怎么可能。与某些外部库相比,python 中的内置类型是否效率低下?
编辑:结构是从 json 文件加载的。所以对象之间没有内部引用
“简单”python 对象,例如int或 float,需要比protobuf.
让我们以 a listof Python 整数作为示例与整数数组进行比较,例如在array.array(ie array.array('i', ...)) 中。
for 的分析array.array很简单:从array.arrays-object 中丢弃一些开销,每个元素只需要 4 个字节(C 整数的大小)。
对于整数列表,情况完全不同:
864 位可执行文件的附加字节)28字节(参见import sys; sys.getsizeof(1)返回 28):引用计数需要 8 个字节,保存指向整数函数表的指针需要 8 个字节,整数值的大小需要 8 个字节( Python 的整数可以比 2^32 大得多),并且至少需要 4 个字节来保存整数值本身。这意味着与可能的 4 个字节(如果我们使用 8 个字节long long int,即 64 位整数)相比,每个 Python 整数的成本高达 40.5 个字节。
与doubles( ie array.array('d',...))的数组相比,带有 Python 浮点数的列表的情况类似,每个元素只需要大约 8 个字节。但是对于列表,我们有:
864 位可执行文件的附加字节)24字节(参见import sys; sys.getsizeof(1.0)返回 24):引用计数需要 8 个字节,8 个字节用于保存指向浮点函数表的指针,8 个字节用于保存double-value 本身。这意味着 Python 浮点对象为 32.5 字节,而 C-double 为 8 字节。
protobuf在内部使用相同的数据表示,array.array因此需要更少的内存(如您所见,大约少 4-5 倍)。numpy.array是数据类型的另一个示例,它保存原始 C 值,因此需要比列表少得多的内存。
如果不需要在字典中搜索,那么将键值对保存在列表中将比在字典中需要更少的内存,因为不必维护用于搜索的结构(这会增加一些内存成本) ) - 这也是导致protobuf-data内存占用较小的另一件事。
回答你的另一个问题:没有内置模块是 Python- 的dict,什么array.array是 Python- 的list,所以我利用这个机会无耻地为我的库插入广告:cykhash.
Sets 和 maps fromcykhash 需要不到Python'S- dict/set内存的25%,但速度差不多。
| 归档时间: |
|
| 查看次数: |
263 次 |
| 最近记录: |