gpt4 book ai didi

python - 一百万个元素的列表在 Python 中会占用多少内存?

转载 作者:IT王子 更新时间:2023-10-28 23:34:03 24 4
gpt4 key购买 nike

根据 redditmetrics.com,Reddit 上有超过一百万个子版 block 。 .

我写了一个反复查询this Reddit API endpoint的脚本直到所有 subreddits 都存储在一个数组中,all_subs:

all_subs = []
for sub in <repeated request here>:
all_subs.append({"name": display_name, "subscribers": subscriber_count})

脚本已经运行了近十个小时,大约完成了一半(每三到四个请求就会受到速率限制)。完成后,我希望有一个这样的数组:

[
{ "name": "AskReddit", "subscribers", 16751677 },
{ "name": "news", "subscribers", 13860169 },
{ "name": "politics", "subscribers", 3350326 },
... # plus one million more entries
]

此列表将占用大约多少内存空间?

最佳答案

这取决于您的 Python 版本和您的系统,但我会帮助您了解它需要多少内存。首先,sys.getsizeof 只返回代表容器的 object 的内存使用情况,而不是容器中的所有元素。

Only the memory consumption directly attributed to the object is accounted for, not the memory consumption of objects it refers to.

If given, default will be returned if the object does not provide means to retrieve the size. Otherwise a TypeError will be raised.

getsizeof() calls the object’s __sizeof__ method and adds an additional garbage collector overhead if the object is managed by the garbage collector.

See recursive sizeof recipe for an example of using getsizeof() recursively to find the size of containers and all their contents.

所以,我已经在交互式解释器 session 中加载了该配方:

因此,CPython list 实际上是一个异构的、可调整大小的数组列表。底层数组只包含指向 Py_Objects 的指针。所以,一个指针占用了一个机器字的内存。在 64 位系统上,这是 64 位,因此是 8 个字节。因此,仅对于容器,大小为 1,000,000 的列表将占用大约 800 万字节,即 8 兆字节。建立一个包含 1000000 个条目的列表证明了这一点:

In [6]: for i in range(1000000):
...: x.append([])
...:

In [7]: import sys

In [8]: sys.getsizeof(x)
Out[8]: 8697464

额外的内存是由 python 对象的开销和底层数组最后留下的额外空间来计算的,以允许高效的 .append 操作。

现在,字典在 Python 中相当重要。只是容器:

In [10]: sys.getsizeof({})
Out[10]: 288

因此,100 万个字典大小的下限是:288000000 字节。所以,一个粗略的下限:

In [12]: 1000000*288 + 1000000*8
Out[12]: 296000000

In [13]: 296000000 * 1e-9 # gigabytes
Out[13]: 0.29600000000000004

因此,您可以预期大约 0.3 GB 的内存。使用recipie和更真实的dict:

In [16]: x = []
...: for i in range(1000000):
...: x.append(dict(name="my name is what", subscribers=23456644))
...:

In [17]: total_size(x)
Out[17]: 296697669

In [18]:

所以,大约 0.3 场演出。现在,这在现代系统中并不多。但是如果你想节省空间,你应该使用 tuple 甚至更好,一个 namedtuple:

In [24]: from collections import namedtuple

In [25]: Record = namedtuple('Record', "name subscribers")

In [26]: x = []
...: for i in range(1000000):
...: x.append(Record(name="my name is what", subscribers=23456644))
...:

In [27]: total_size(x)
Out[27]: 72697556

或者,以千兆字节为单位:

In [29]: total_size(x)*1e-9
Out[29]: 0.07269755600000001

namedtuple 就像 tuple 一样工作,但您可以使用 names 访问字段:

In [30]: r = x[0]

In [31]: r.name
Out[31]: 'my name is what'

In [32]: r.subscribers
Out[32]: 23456644

关于python - 一百万个元素的列表在 Python 中会占用多少内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43404210/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com