查找字符串集与字节字符串集的内存大小



Edit:Python中数百万字符串列表的内存使用情况的答案也可以适用于集合。


通过分析我的机器上的RAM使用情况(使用进程管理器(,我注意到像'abcd'这样的数百万字符串集所占用的内存比数百万字节的b'abcd'集要少得多(编辑:我错了,这是由于其他地方的错误(。我想测试一下:

import random, string, sys
randomstring = lambda length: ''.join(random.choice(string.ascii_lowercase) for _ in range(length))
s1 = {randomstring(10) for i in range(100_000)}
s2 = {randomstring(50) for i in range(100_000)}
s3 = {randomstring(10).encode() for i in range(100_000)} 
s4 = {randomstring(50).encode() for i in range(100_000)} 
print(sys.getsizeof(s1), sys.getsizeof(s2), sys.getsizeof(s3), sys.getsizeof(s4))

但在这里,它总是给出相同的大小:4194528,而大小应该随因子x5而变化,并且对于字符串与字节的情况可能不同。

如何测量这些集合及其所有元素所占用的内存大小

注意:我知道在Python中找到一个结构占用的整个内存并不容易(另请参阅Python结构的内存大小(,因为我们需要考虑所有链接的元素。

TL;DR:Python中是否有一个工具可以自动测量集合的内存大小+内部引用(指针?(、哈希表桶、集合中托管的元素(此处为字符串(占用的内存。。。?简而言之:这组字符串所需的每个字节。这样的记忆测量工具存在吗?

sys.getsizeof不测量完整目标数据结构的大小。它只测量包含对字符串/字节对象的引用的集合对象占用的内存。引用不包括在返回的内存消耗中(即,它不会在目标数据结构的每个对象中递归地遍历(。在64位平台上,引用通常需要8个字节,CPython集不像列表那样紧凑:它像哈希表一样实现,有许多存储桶,有些存储桶未使用。事实上,这对于该数据结构的快速性是强制性的(通常,占用率应为50%-90%(。此外,每个bucket包含一个散列,该散列通常占用8个字节。

字符串本身占用的空间比桶大得多(至少在我的机器上(:

sys.getsizeof(randomstring(50))           # 99
sys.getsizeof(randomstring(50).encode())  # 83

在我的机器上,CPython字符串比字节大16个字节。

最新更新