我做多少内存每个Python的数组类型的花费,这是一个实验list,tuple,set,dict,np.array.然后我得到了以下结果.
(x轴是数组的长度,y轴是内存大小.)
我发现Python set花费的内存量也会逐步增加dict,而其他内存则会按照我的预期线性增长.我想知道是什么让他们与众不同
我使用了以下get_size()功能.(参考)
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
Run Code Online (Sandbox Code Playgroud)
我用100个间隔测量了从0到10,000的内存.
CPython 集合和字典始终使用两倍大小的内部哈希表。list、tuple、 和numpy.ndarray都在其底层内存缓冲区的大小方面具有更大的灵活性,但set和dict被硬编码为使用二次方表大小。该实现无法在非 2 的幂表大小的情况下运行。参见Objects/dictobject.c和Objects/setobject.c。
图表中的跳跃是指当表大小跳跃到新的 2 的幂时。
顺便说一句,你的get_size效果不太好。例如,它有两个影响numpy.ndarray案例的错误几乎抵消了(但不完全抵消)。它尝试将 NumPy 数组元素的大小添加到整个数组的大小,但对于 NumPy 数组,元素的大小已由 计算在内getsizeof。此外,它还使用 确定对象标识id,但通过迭代 NumPy 数组生成的对象是动态创建的,并立即消亡,因此它们的id值不是唯一的。实际上,这可能会超出表示数组元素的对象大小的一到两倍的大小。