我有以下代码:
keywordindex = cPickle.load(open('keywordindex.p','rb'))#contains~340 thousand items
masterIndex = {}
indexes = [keywordindex]
for partialIndex in indexes:
start = time.time()
for key in partialIndex.iterkeys():
if key not in masterIndex.keys():
masterIndex[key]= partialIndex[key]
elif key in masterIndex.keys():
masterIndex[key].extend(partialIndex[key])
cPickle.dump(masterIndex,open('MasterIndex.p','wb'))
print int(time.time() - start), ' seconds'#every thousand loops
并且我在循环运行时遇到性能下降,前10万次大约需要5秒钟,但每10万左右需要一秒钟,直到它花费3倍的时间。我试图以各种可能的方式简化代码,但我似乎无法弄清楚导致它的原因。是否有一个原因?这不是内存问题,我的使用率仅为30%
答案 0 :(得分:8)
此块包含两个编码效率极低的实例:
if key not in masterIndex.keys():
masterIndex[key]= partialIndex[key]
elif key in masterIndex.keys():
masterIndex[key].extend(partialIndex[key])
首先,密钥在masterIndex
中是否存在,因此elif
测试根本没有有用的点。如果not in
测试失败,则in
测试必须成功。所以这段代码也是如此:
if key not in masterIndex.keys():
masterIndex[key]= partialIndex[key]
else:
masterIndex[key].extend(partialIndex[key])
其次,masterIndex
是dict
。 Dicts支持非常有效的成员资格测试,无需您的任何帮助;-)通过将其密钥实现到一个列表(通过.keys()
),您正在改变应该是一个超快的字典查找列表上一个非常慢的线性搜索。所以这样做:
if key not in masterIndex:
masterIndex[key]= partialIndex[key]
else:
masterIndex[key].extend(partialIndex[key])
代码运行速度会快得多。
答案 1 :(得分:3)
您无需搜索masterIndex.keys()
。另外,只需使用空else
子句:
if key not in masterIndex:
...
else:
...
dict上的in
运算符查询该字典的键,该操作的时间复杂度平均为O(1)。