如何在Python中设置字典的初始大小?
我将约400万个不同的密钥放入Python字典中。 创建此字典需要大约15分钟,并在我的机器上消耗大约4GB的内存。字典完全创建后,查询字典很快。如何在Python中设置字典的初始大小?
我怀疑字典创建是非常耗费资源的,因为字典经常被重新编译(随着它的增长)。 是否可以创建一个Python的字典与一些初始大小或桶号?
我的字典从一个数字指向一个对象。
class MyObject(object):
def __init__(self):
# some fields...
d = {}
d[i] = MyObject() # 4M times on different key...
由于性能问题,最好测量。这里有一些时间:
d = {}
for i in xrange(4000000):
d[i] = None
# 722ms
d = dict(itertools.izip(xrange(4000000), itertools.repeat(None)))
# 634ms
dict.fromkeys(xrange(4000000))
# 558ms
s = set(xrange(4000000))
dict.fromkeys(s)
# Not including set construction 353ms
最后一个选项不做任何调整大小,它只是从集合中复制散列并增加引用。正如你所看到的,调整大小并没有花费很多时间。这可能是你的对象创建缓慢。
无论如何初始化字典,填充数据总是需要很长时间。看起来确实所有的时间都花在创建对象上。谢谢! – tkokoszka 2009-08-19 10:32:21
你可以尝试从内容与dict.fromkeys
类方法填充分隔密钥散列。它将创建一个已知大小的dict
,所有值默认为None
或您选择的值。之后,您可以遍历它来填充值。它会帮助你计算所有密钥的实际散列。不知道你是否能够显着提高速度。
如果你知道C,你可以看看dictobject.c和the Notes on Optimizing Dictionaries 。您会注意到参数PyDict_MINSIZE:
PyDict_MINSIZE。目前设置为8.
此参数在dictobject.h中定义。所以你可能编译Python时改变它,但这可能是一个坏主意。
我尝试:
a = dict.fromkeys((range(4000000)))
它创建在约3秒,4个000 000项的字典。之后,设定值非常快。所以我认为dict.fromkey是最快的方式。
+1提到dict.fromkeys()。但是,使用range()来指定键意味着你最终得到了顺序键的字典。如果这是必需的,为什么不使用列表?a = [None] * 4000000 – 2009-08-19 09:53:23
这不是直接的解决方案,只是一个演示,你可以使用键来预先生成字典在一个非常排序的时间。 – 2009-08-19 11:47:28
符合@ShawnChin提出的观点,如果你不希望数字1 ... 4M作为关键字?或者更一般地说,如果你事先不知道你的钥匙,但你只知道他们有几百万? – posdef 2016-03-10 11:29:32
你是否用初始化所有键的新“空”相同类型的实例?是不是可以写一个defaultdict或什么东西来创建访问它时的对象?
非常类似于http://stackoverflow.com/questions/311775/python-create-a-list-dict-with-initial-capacity – 2009-08-19 09:13:52
你能让我们知道你的密钥的来源/格式,所以我们可以改进an鱼? – 2009-08-19 09:39:44
它是一个数字的关键 – tkokoszka 2009-08-19 10:09:11