Python集花费的内存量会逐步增加

2024-04-19 13:15:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我做了一个关于每个Python数组类型花费多少内存的实验,即listtuplesetdictnp.array。然后我得到了以下结果。你知道吗

The amount of memory Python array types spend

(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的记忆。你知道吗

我的代码:https://repl.it/repls/WanEsteemedLines


Tags: 内存innoneidobjforsizeget
1条回答
网友
1楼 · 发布于 2024-04-19 13:15:59

CPython集合和dict总是使用两个大小的内部哈希表的幂。listtuplenumpy.ndarray对于其底层内存缓冲区的大小都有更大的灵活性,但是setdict被硬编码为使用两个表大小的幂。实现不能在表大小为2的非幂次函数中运行。见^{}^{}。你知道吗

图表中的跳转是当表大小跳转到新的二次方时。你知道吗

顺便说一句,你的get_size工作不太好。例如,它有两个影响numpy.ndarray情况的bug,它们几乎抵消了(但不完全抵消)。它试图将NumPy数组的元素大小添加到整个数组的大小中,但是对于NumPy数组,元素的大小已经由getsizeof计算。此外,它还使用id确定对象标识,但是通过遍历NumPy数组生成的对象是动态创建的,并且会立即消亡,因此它们的id值不是唯一的。实际上,这可能会将表示数组元素的对象的大小的一到两倍计算过多。你知道吗

相关问题 更多 >