我正在为一个性能非常重要的应用程序编写代码。我想知道为什么defaultdict似乎比setdefault更快。
我希望能够使用setdefault,主要是因为我不喜欢嵌套的defaultdict的打印输出(参见下面的实现)。
在我的代码中,我需要测试element_id是否已经是字典的关键字。
下面是我正在测试的两个函数:
def defaultdictfunc(subcases,other_ids,element_ids):
dict_name= defaultdict(lambda: defaultdict(lambda: defaultdict(dict)))
for subcase in subcases:
for other_id in other_ids:
for element_id in element_ids:
if element_id in dict_name[subcase][other_id]:
# error duplicate element_id
pass
else:
dict_name[subcase][other_id][element_id]=0
return dict_name
def setdefaultfunc(subcases,other_ids,element_ids):
dict_name={}
for subcase in subcases:
for other_id in other_ids:
for element_id in element_ids:
if element_id in dict_name.setdefault(subcase,{}).setdefault(other_id,{}):
# error duplicate element_id
pass
else:
dict_name[subcase][other_id][element_id]=0
return dict_nameIPython输入和输出:
In [1]: from numpy.random import randint
In [2]: subcases,other_ids,element_ids=(randint(0,100,100),randint(0,100,100),randint(0,100,100))
In [5]: from collections import defaultdict
In [6]: defaultdictfunc(subcases,other_ids,element_ids)==setdefaultfunc(subcases,other_ids,element_ids)
Out[6]: True
In [7]: %timeit defaultdictfunc(subcases,other_ids,element_ids)
10 loops, best of 3: 177 ms per loop
In [8]: % timeit setdefaultfunc(subcases,other_ids,element_ids)
1 loops, best of 3: 351 ms per loop为什么setdefaultfunc变慢了。我以为底层代码应该是一样的。有没有办法提高它的速度?
谢谢
发布于 2018-05-14 05:44:55
根据用户aneroid
defaultdict比dict.setdefault()更快是有道理的,因为前者在创建时设置整个字典的默认值,而
()在读取时按元素设置。使用setdefault的一个原因是,当您分配的默认值是基于键(或某项)而不是整个dict的通用默认值时。
发布于 2019-09-24 00:29:05
setdefaultfunc是最糟糕的,因为您在循环中多次调用dict构造函数(因为{}等同于dict()),而defaultdict通过自己的设计避免了这一点。
只需很小的更改,就可以轻松地改进setdefaultfunc
def setdefaultfunc2(subcases,other_ids,element_ids):
dict_name={}
for subcase in subcases:
subcase_dict = dict_name.setdefault(subcase,{})
for other_id in other_ids:
other_id_dict = subcase_dict.setdefault(other_id,{})
for element_id in element_ids:
if element_id in other_id_dict:
# error duplicate element_id
pass
else:
other_id_dict[element_id]=0
return dict_name进行此更改后,我的机器中的结果为:
In [37]: defaultdictfunc(subcases,other_ids,element_ids)==setdefaultfunc2(subcases,other_ids,element_ids)
Out[37]: True
In [38]: %timeit defaultdictfunc(subcases,other_ids,element_ids)
286 ms ± 8.55 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [39]: %timeit setdefaultfunc(subcases,other_ids,element_ids)
434 ms ± 1.78 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [40]: %timeit setdefaultfunc2(subcases,other_ids,element_ids)
174 ms ± 348 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)在国际海事组织,defaultdict没有提供足够的性能增益来使其值得使用。
https://stackoverflow.com/questions/38625608
复制相似问题