sys.getsizeof() results don't quite correlate to structure size
我正在尝试创建大小为1 MB的列表。当以下代码工作时:
1 2 3 | dummy = ['a' for i in xrange(0, 1024)] sys.getsizeof(dummy) Out[1]: 9032 |
以下代码不起作用。
1 2 3 4 5 6 7 | import os import sys dummy = [] dummy.append((os.urandom(1024)) sys.getsizeof(dummy) Out[1]: 104 |
号
有人能解释为什么吗?
如果您想知道为什么我不使用第一个代码片段,我正在编写一个程序,通过编写一个for循环,将块(大小为1b、1kb和1MB)写入内存,来测试内存。
1 2 3 4 | 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() |
如果检查列表的大小,它将提供列表数据结构的大小,包括指向其组成元素的指针。它不会考虑元素的大小。
1 2 3 4 5 | 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 |
空表大小:
包含119个元素的列表的大小:
所以我们需要的是一个不变的数据结构,它不需要保留这个缓冲区——
1 2 3 4 5 6 | 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 2 | sys.getsizeof('') == 37 sys.getsizeof('1') == 38 # each character adds 1 byte |
对于1 MB,我们需要987个字符:
1 | sys.getsizeof('1'*987) == 1024 |
。
这是实际大小,而不仅仅是指针的大小。