环路性能下降

时间:2014-01-14 03:52:24

标签: python dictionary pickle

我有以下代码:

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%

2 个答案:

答案 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])

其次,masterIndexdict。 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)。