我做了一个关于每个Python数组类型花费多少内存的实验,即list
、tuple
、set
、dict
、np.array
。然后我得到了以下结果。你知道吗
(x轴是数组的长度,y轴是内存大小。)
我发现Python set
花费的内存量是逐步增加的(也是dict
),而其他Python的内存量则如我所预期的那样线性增加。我想知道是什么让他们与众不同。你知道吗
我使用了下面的get_size()
函数。(reference)
def get_size(obj, seen = None):
size = sys.getsizeof(obj)
if seen is None:
seen = set()
obj_id = id(obj)
if obj_id in seen:
return 0
seen.add(obj_id)
if isinstance(obj, dict):
size += sum([get_size(v, seen) for v in obj.values()])
size += sum([get_size(k, seen) for k in obj.keys()])
elif hasattr(obj, '__dict__'):
size += get_size(obj.__dict__, seen)
elif hasattr(obj, '__iter__') and not isinstance(obj, (str, bytes, bytearray)):
size += sum([get_size(i, seen) for i in obj])
return size
我以100个间隔测量了从0到10000的记忆。你知道吗
CPython集合和dict总是使用两个大小的内部哈希表的幂。} 和^{} 。你知道吗
list
、tuple
和numpy.ndarray
对于其底层内存缓冲区的大小都有更大的灵活性,但是set
和dict
被硬编码为使用两个表大小的幂。实现不能在表大小为2的非幂次函数中运行。见^{图表中的跳转是当表大小跳转到新的二次方时。你知道吗
顺便说一句,你的
get_size
工作不太好。例如,它有两个影响numpy.ndarray
情况的bug,它们几乎抵消了(但不完全抵消)。它试图将NumPy数组的元素大小添加到整个数组的大小中,但是对于NumPy数组,元素的大小已经由getsizeof
计算。此外,它还使用id
确定对象标识,但是通过遍历NumPy数组生成的对象是动态创建的,并且会立即消亡,因此它们的id
值不是唯一的。实际上,这可能会将表示数组元素的对象的大小的一到两倍计算过多。你知道吗相关问题 更多 >
编程相关推荐