Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Python中设置字典的初始大小?_Python_Performance_Dictionary - Fatal编程技术网

如何在Python中设置字典的初始大小?

如何在Python中设置字典的初始大小?,python,performance,dictionary,Python,Performance,Dictionary,我在Python字典中输入了大约400万个不同的键。 创建此词典大约需要15分钟,并且在我的机器上消耗大约4GB的内存。完全创建字典后,查询字典的速度很快 我怀疑字典的创建是如此消耗资源,因为字典经常被重新整理(因为它增长得非常快)。 是否可以用Python创建一个具有初始大小或bucket编号的字典 我的字典从一个数字指向一个对象 class MyObject: def __init__(self): # some fields... d = {} d[i] = My

我在Python字典中输入了大约400万个不同的键。 创建此词典大约需要15分钟,并且在我的机器上消耗大约4GB的内存。完全创建字典后,查询字典的速度很快

我怀疑字典的创建是如此消耗资源,因为字典经常被重新整理(因为它增长得非常快)。 是否可以用Python创建一个具有初始大小或bucket编号的字典

我的字典从一个数字指向一个对象

class MyObject:
    def __init__(self):
        # some fields...

d = {}
d[i] = MyObject()  # 4M times on different key...

您可以尝试使用classmethod将密钥散列与内容填充分开。它将创建一个已知大小的
dict
,所有值默认为
None
或您选择的值。之后,您可以对其进行迭代以填充值。它将帮助您计算所有键的实际哈希时间。不确定你是否能显著提高速度。

如果你的数据需要/可以存储在光盘上,也许你可以将数据存储在光盘中,或者用它来加载/存储你的字典。

如果你知道C,你可以查看和。在这里,您会注意到参数PyDict_MINSIZE:

PyDict_MINSIZE。当前设置为8

此参数在中定义。因此,您可以在编译Python时更改它,但这可能不是一个好主意。

我尝试了:

a = dict.fromkeys((range(4000000)))

它在大约3秒钟内创建了一个包含400000个条目的字典。之后,设置值的速度非常快。因此,我想dict.fromkey绝对是一个好办法。

对于性能问题,最好进行测量。以下是一些时间安排:

 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

最后一个选项不进行任何大小调整,它只是从集合中复制哈希值并增加引用。正如您所看到的,调整大小不会花费很多时间。可能是您的对象创建缓慢

是否使用相同类型的新“空”实例初始化所有密钥?是否无法编写defaultdict或在访问对象时创建对象的东西?

非常类似于您能否让我们知道密钥的来源/格式,以便我们改进anwsers?最后我了解到我的性能问题不是来自dict初始化。使用插槽解决了这些问题,请参见:u应使用数据库并根据需要将数据从数据库拉入缓存+1用于提及dict.fromkeys()。然而,使用range()指定键意味着您最终会得到一个顺序键的dict。如果这是必需的,为什么不使用列表呢?a=[None]*4000000这不是直接的解决方案,只是一个演示,您可以使用fromkeys在非常短的时间内预生成dict。根据@ShawnChin提出的要点,如果您不希望数字1…4M作为键,该怎么办?或者更一般地说,如果你事先不知道你的密钥,但你只知道它们是以百万计的呢?不管我如何初始化字典,用数据填充它总是需要很多时间。看起来所有的时间都花在了对象创建上。谢谢