9

假设有一个 dict 变量在运行时变得非常大 - 多达数百万个键:值对。

这个变量是否存储在 RAM 中,有效地使用了所有可用内存并减慢了系统的其余部分?

要求解释器显示整个 dict 是一个坏主意,但只要一次访问一个键就可以了吗?

4

4 回答 4

10

是的,字典将存储在进程内存中。因此,如果它变得足够大以至于系统 RAM 中没有足够的空间,那么随着系统开始与磁盘交换内存和从磁盘交换内存,您可能会看到大幅减速。

其他人则说,几百万件不应该造成问题;我不确定。dict 开销本身(在计算键和值占用的内存之前)很重要。对于 Python 2.6 或更高版本,sys.getsizeof提供了一些关于各种 Python 结构占用多少 RAM 的有用信息。一些快速的结果,来自 64 位 OS X 机器上的 Python 2.6:

>>> from sys import getsizeof
>>> getsizeof(dict((n, 0) for n in range(5462)))/5462.
144.03368729403149
>>> getsizeof(dict((n, 0) for n in range(5461)))/5461.
36.053470060428495

因此,在这台机器上,dict 开销在每个项目 36 个字节和每个项目 144 个字节之间变化(确切值取决于字典的内部哈希表的完整程度;这里 5461 = 2**14//3 是阈值之一,其中内部哈希表被放大)。那是在为 dict 项目本身添加开销之前;如果它们都是短字符串(例如 6 个字符或更少),那么每个项目仍然会增加 >= 80 个字节(如果许多不同的键共享相同的值,可能会更少)。

因此,在一台典型的机器上用完 RAM 并不需要百万个 dict 项目。

于 2010-04-19T19:29:06.347 回答
5

数以百万计的项目的主要关注点不是字典本身,而是每个项目占用多少空间。不过,除非你做一些奇怪的事情,否则它们可能应该适合。

但是,如果您有一个包含数百万个键的 dict,那么您可能做错了什么。您应该执行以下一项或两项操作:

  1. 弄清楚你应该实际使用什么数据结构,因为单个 dict 可能不是正确的答案。这究竟是什么取决于你在做什么。

  2. 使用数据库。你的 Python 应该带有一个 sqlite3 模块,所以这是一个开始。

于 2010-04-19T19:08:16.023 回答
4

是的,Pythondict存储在 RAM 中。然而,几百万个密钥对于现代计算机来说不是问题。如果您需要越来越多的数据并且 RAM 已用完,请考虑使用真实数据库。选项包括像 SQLite 这样的关系数据库(顺便说一下,内置在 Python 中)或像 Redis 这样的键值存储。

在解释器中显示数百万个项目没有什么意义,但访问单个元素应该仍然非常有效。

于 2010-04-19T19:02:46.103 回答
2

据我所知,Python 使用最好的散列算法,因此您可能会获得最佳的内存效率和性能。现在,整个内容是保存在 RAM 中还是提交到交换文件取决于您的操作系统,并且取决于您拥有的 RAM 量。如果只是尝试一下,我想说的是最好的:

from random import randint
a = {}
for i in xrange(10*10**6):
    a[i] = i

当你运行它时,它看起来如何?在我的系统上占用大约 350Mb,至少可以说是可以管理的。

于 2010-04-19T19:06:03.950 回答