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
According to user aneroid:
The
setdefaultfunc
is worst because you call the dict constructor several times in the loop (since{}
is equivalent todict()
), whiledefaultdict
avoid this by its own design.With a small change, you can easily improve the
setdefaultfunc
:With this change, the results in my machine were:
IMO,
defaultdict
does not provide enought performance gain to make worth using it.