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个字节。