我有以下代码:
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%
这个块包含两个非常低效的编码实例:
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支持非常有效的成员资格测试,无需您的任何帮助;-)通过将其密钥实现为列表(via .keys()
),您将改变应该是一个超快速的字典查找到列表中的一个非常慢的线性搜索.所以这样做:
if key not in masterIndex: masterIndex[key]= partialIndex[key] else: masterIndex[key].extend(partialIndex[key])
代码将运行得更快.