【问题标题】:sys.getsizeof() results don't quite correlate to structure sizesys.getsizeof() 结果与结构大小不完全相关
【发布时间】:2016-02-11 07:04:10
【问题描述】:

我正在尝试创建一个大小为 1 MB 的列表。虽然以下代码有效:

dummy = ['a' for i in xrange(0, 1024)]
sys.getsizeof(dummy)
Out[1]: 9032

以下代码不起作用。

import os
import sys

dummy = []
dummy.append((os.urandom(1024))
sys.getsizeof(dummy)
Out[1]: 104

谁能解释一下原因?

如果您想知道为什么我不使用第一个代码 sn-p,我正在编写一个程序来对我的内存进行基准测试,方法是编写一个 for 循环,将块(大小为 1 B、1 KB 和 1 MB)写入记忆。

start = time.time() 
for i in xrange(1, (1024 * 10)):  
     dummy.append(os.urandom(1024)) #loop to write 1 MB blocks into memory
end = time.time()

【问题讨论】:

  • 或许能帮上忙:sys.getsizeof(b"a"*(1024-37))
  • 你不会得到一个理智的记忆基准,除了你的代码之外还有很多其他事情发生。对于这项任务,Python 是一个糟糕的工具选择。

标签: python memory data-structures


【解决方案1】:

如果您检查列表的大小,它将提供列表数据结构的大小,包括指向其组成元素的指针。它不会考虑元素的大小。

str1_size = sys.getsizeof(['a' for i in xrange(0, 1024)])
str2_size = sys.getsizeof(['abc' for i in xrange(0, 1024)])
int_size = sys.getsizeof([123 for i in xrange(0, 1024)])
none_size = sys.getsizeof([None for i in xrange(0, 1024)])
str1_size == str2_size == int_size == none_size

空列表大小:sys.getsizeof([]) == 72
添加元素:sys.getsizeof([1]) == 80
添加另一个元素:sys.getsizeof([1, 1]) == 88
所以每个元素增加 4 个字节。
要获得 1024 字节,我们需要 (1024 - 72) / 8 = 119 元素。

包含 119 个元素的列表的大小:sys.getsizeof([None for i in xrange(0, 119)]) == 1080
这是因为列表维护了一个额外的缓冲区来插入更多的项目,因此它不必每次都调整大小。 (对于 107 到 126 之间的元素数量,大小与 1080 相同)。

所以我们需要的是一个不可变的数据结构,它不需要保留这个缓冲区 - tuple

empty_tuple_size = sys.getsizeof(())                     # 56
single_element_size = sys.getsizeof((1,))                # 64
pointer_size = single_element_size - empty_tuple_size    # 8
n_1mb = (1024 - empty_tuple_size) / pointer_size         # (1024 - 56) / 8 = 121
tuple_1mb = (1,) * n_1mb
sys.getsizeof(tuple_1mb) == 1024

这就是你获得 1MB 数据结构的答案:(1,)*121

但请注意,这只是元组的大小和组成指针。对于总大小,您实际上需要将各个元素的大小相加。


替代:

sys.getsizeof('') == 37
sys.getsizeof('1') == 38     # each character adds 1 byte

对于 1 MB,我们需要 987 个字符:

sys.getsizeof('1'*987) == 1024

这是实际大小,而不仅仅是指针的大小。

【讨论】:

    猜你喜欢
    • 2019-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-27
    • 2020-03-12
    • 1970-01-01
    • 1970-01-01
    • 2016-05-02
    相关资源
    最近更新 更多