【发布时间】:2021-08-25 11:36:58
【问题描述】:
众所周知,Python(或至少是 CPython)缓存了一些第一个整数。也就是说,以下成立
a = 1
b = 1
print(a is b) # True
同时
a = 1000
b = 1000
print(a is b) # False
更广泛地说,我们可以使用下面列出的方法来查看缓存了哪些基本对象(或者“是单例”,如果您愿意的话)。
def does_survive_pickling(obj):
after_pickling = pkl.loads(pkl.dumps(obj))
return obj is after_pickling
我的问题是
-
表现出这种行为的对象是什么? (比如说,“存活”酸洗方法)
- 在我的 CPython 3.9.1 中,它们至少是 [-5, 256] 中的整数(对应的字符也是如此,即 8 位 ACII)、
()、None、True、False和 @ 987654328@。还有其他人吗?
- 在我的 CPython 3.9.1 中,它们至少是 [-5, 256] 中的整数(对应的字符也是如此,即 8 位 ACII)、
-
这些对象的数量和种类取决于什么条件?
-
我认为 Python 的实现非常重要。
-
还有什么(比如,对于 CPython)?版本?硬件(例如 32 位与 64 位处理器)?还有其他的吗?
-
-
是否有可能在某处找到这些信息? (在文档中?)
如果有任何 cmets、答案或有用的链接,我会很高兴。谢谢!
也许 CPython 的行为对我来说是唯一真正重要的。但是,出于好奇,欢迎提供有关 PyPy 和其他内容的信息。
作为背景,我正在开发一个需要管理其内存资源的库。因此,我努力学习更多关于 Python 内存管理的知识。在这种情况下,我对 pickled-unpickled 对象(更普遍地是序列化-反序列化)的内存占用感兴趣。
比如说,你从一堆内部结构相互交织的对象开始。如果将这些对象中的每一个都保存到磁盘并再次加载,会发生什么(内存消耗增加了多少)?
如果是一些1的嵌套列表,与1000的相同列表有很大的不同。
【问题讨论】:
-
“是否有可能在某处找到这些信息?” - 是的,在源代码中,因为这些只是实现细节。您问题的第二部分非常广泛,并且本身就是一个不同的问题,这使得您的整个问题对于 SO...
-
@ThierryLathuille 我知道这可能是一个深深隐藏的小实现细节。不过,我不确定。如果它真的是一个非常不稳定的功能,我将不再使用它。但也许(再次,我不知道,这就是我要问的原因)它在 Python 版本(甚至可能是实现)之间更普遍的行为相当稳定。在这种情况下,了解这一点很有用。 ... 例如
iter用于dict的插入顺序曾经是CPython 的实现细节,现在它是必需的功能(但是,请理解这里的细节级别完全不同)。 -
插入顺序的保留是仅在一个 CPython 版本中的实现细节,紧接在其升级为语言功能之前。我相信它当时也是这样宣布的:它是有意提前推出一个版本作为测试用例的。
标签: python memory-management python-internals