Python大变量内存使用
假设有一个字典变量,它在运行过程中变得非常大,里面的键值对可能达到几百万个。
这个变量会存储在内存中,也就是说,它会占用所有可用的内存,这样可能会导致系统变慢。
一次性让解释器显示整个字典是个糟糕的主意,但如果每次只访问一个键,那这样做可以吗?
4 个回答
没错,Python里的dict
(字典)是存储在内存里的。对于现代电脑来说,几百万个键值对并不是问题。不过,如果你需要存储越来越多的数据,而内存又不够用了,那就可以考虑用真正的数据库。可以选择像SQLite这样的关系型数据库(顺便说一下,Python里自带这个)或者像Redis这样的键值存储。
在解释器里显示几百万个项目是没有太大意义的,但访问单个元素还是非常高效的。
对于有几百万个项目的字典,主要的问题不是字典本身,而是这些项目占用了多少空间。不过,除非你在做一些奇怪的事情,否则它们应该是可以放下的。
如果你的字典有几百万个键,那你可能做错了什么。你应该考虑做以下一项或两项:
想想你应该使用什么样的数据结构,因为单靠一个字典可能不是正确的选择。具体应该用什么,得看你在做什么。
使用数据库。你的Python应该自带一个sqlite3模块,这可以作为一个开始。
是的,字典会存储在进程的内存中。所以如果它变得足够大,以至于系统的内存不够用,你就会发现系统会变得非常慢,因为它开始把内存中的数据交换到硬盘上。
有人说几百万个项目应该没问题;我对此不太确定。字典本身的开销(还没算上键和值占用的内存)就很大。对于Python 2.6或更高版本,sys.getsizeof可以提供一些关于各种Python结构占用多少内存的有用信息。以下是一些在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
在这台机器上,字典的开销在每个项目36字节到144字节之间(具体数值取决于字典内部哈希表的填充程度;这里5461 = 2**14//3是一个阈值,当达到这个值时,内部哈希表会扩大)。而这还不包括字典项本身的开销;如果它们都是短字符串(比如6个字符或更少),那么每个项目还会增加至少80字节的开销(如果许多不同的键共享同一个值,可能会少一些)。
所以在一台普通的机器上,耗尽内存并不需要太多的字典项目。