I am writing code for an application where performance is important. I am wondering why defaultdict seems to be faster then setdefault.
I would like to be able to use setdefault, mostly because i do not like the print output of the nested defaultdict (see implementation below).
In my code, i need to test if element_id is already a key of the dict.
Here are the two functions that i am testing:
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_name
IPython input and output:
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
Why is setdefaultfunc slower. I thought the underlying code would be the same. Is there a way to improve its speed?
Thanks
defaultdict] is simpler and faster than an equivalent technique usingdict.setdefault()." To work around the printing issue, it is easy (and quick) to convert adefaultdictback to a regulardictby usingdict(dict_name). - unutbudefaultdictis faster thatdict.setdefault()since the former sets its default for the entire dict at creation time, whereassetdefault()does it per element when it is read. One reason to usesetdefaultis when the default you assign is based on the key (or something) rather than a generic default for the entire dict. - aneroid