gpt4 book ai didi

Python内存序列化

转载 作者:太空狗 更新时间:2023-10-29 18:28:21 26 4
gpt4 key购买 nike

我想知道是否有人可能知道以下问题的答案。

我正在使用 Python 构建一个基于字符的后缀树。树中有超过 1100 万个节点,可容纳大约 3GB 的内存。这是通过使用 slot 类方法而不是 Dict 方法从 7GB 减少的。

当我序列化树(使用最高协议(protocol))时,生成的文件小一百多倍。

当我重新加载 pickled 文件时,它再次消耗了 3GB 内存。这种额外的开销从何而来,是否与 Python 处理类实例的内存引用有关?

更新

感谢 larsmans 和 Gurgeh 非常有用的解释和建议。我将这棵树用作文本语料库的信息检索界面的一部分。

我最初将子项(最多 30 个)存储为 Numpy 数组,然后尝试了硬件版本 (ctypes.py_object*30)、Python 数组 (ArrayType ),以及字典和集合类型。

列表似乎做得更好(使用 guppy 来分析内存,以及 __slots__['variable',...]),但如果我可以。我在数组方面遇到的唯一问题是必须提前指定它们的大小,这会导致只有一个 child 的节点有点冗余,而我有很多这样的 child 。 ;-)

构建树后,我打算通过第二遍将其转换为概率树,但也许我可以在构建树时执行此操作。由于构建时间对我来说不是太重要,array.array() 听起来像是有用的尝试,感谢您的提示,非常感谢。

我会告诉你进展如何。

最佳答案

如果你尝试 pickle 一个空列表,你会得到:

>>> s = StringIO()
>>> pickle.dump([], s)
>>> s.getvalue()
'(l.'

类似地,'(d.' 用于空的 dict。这是三个字节。然而,in-memory representation of a list 包含

  • 引用计数
  • 一个类型 ID,依次包含指向类型名称的指针和用于内存分配的簿记信息
  • 指向实际元素指针的向量的指针
  • 还有更多簿记信息。

在我的机器上,它有 64 位指针,Python 列表 header 对象的 sizeof 是 40 字节,所以这是一个数量级。我假设一个空的 dict 会有相似的大小。

然后,listdict 都使用过度分配策略来获得amortized O(1) performance对于它们的主要操作,malloc 引入了开销、对齐、您可能知道或什至可能不知道的成员属性以及各种其他因素,这些因素使您处于第二个数量级。

总结:pickle 是一种非常好的 Python 对象压缩算法:)

关于Python内存序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6041395/

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