2014-02-14 51 views
0

for循環在執行時間上相當昂貴。我正在構建一個修正算法,並且使用了peter norvig的拼寫修正代碼。我對其進行了一些修改,並意識到執行數千字優化所花費的時間太長。加速執行,Python

該算法檢查1和2編輯距離並糾正它。我已經做到了3。所以這可能會增加時間(我不確定)。這裏是最高的出現的單詞作爲參考結束的一部分:

def correct(word): 
    candidates = (known([word]).union(known(edits1(word)))).union(known_edits2(word).union(known_edits3(word)) or [word]) # this is where the problem is 

    candidate_new = [] 
    for candidate in candidates: #this statement isnt the problem 
     if soundex(candidate) == soundex(word): 
      candidate_new.append(candidate) 
    return max(candidate_new, key=(NWORDS.get)) 

它看起來像語句0​​增加了執行時間。你可以很容易地看看彼得諾維格的代碼,點擊here
我已經找到了問題。它在聲明中

candidates = (known([word]).union(known(edits1(word))) 
      ).union(known_edits2(word).union(known_edits3(word)) or [word]) 

其中,

def known_edits3(word): 
    return set(e3 for e1 in edits1(word) for e2 in edits1(e1) 
             for e3 in edits1(e2) if e3 in NWORDS) 

可以看出,有3內edits3循環增加執行時間3倍。 edits2有2個for循環。所以這是罪魁禍首。

如何最小化此表達式? 可以幫助itertools.repeat這個?

+0

與*相比增加執行時間* –

+1

先嚐試列表理解,看看是否改善了事情:'候選人候選人=候選人候選人如果soundex(候選人)== soundex(單詞)]' – Evert

+0

@Evert我很好奇,但爲什麼會列表理解有什麼可衡量的影響? –

回答

2

一對夫婦的方式來提高性能在這裏:

  1. 使用列表理解(或發電機)
  2. 不計算在每個迭代

的代碼將減少到同樣的事情:

def correct(word): 
    candidates = (known([word]).union(known(edits1(word)))).union(known_edits2(word).union(known_edits3(word)) or [word]) 

    # Compute soundex outside the loop 
    soundex_word = soundex(word) 

    # List compre 
    candidate_new = [candidate for candidate in candidates if soundex(candidate) == soundex_word] 

    # Or Generator. This will save memory 
    candidate_new = (candidate for candidate in candidates if soundex(candidate) == soundex_word) 

    return max(candidate_new, key=(NWORDS.get)) 

另一個增強是基於這樣一個事實,即你只需要e MAX候選人

def correct(word): 
    candidates = (known([word]).union(known(edits1(word)))).union(known_edits2(word).union(known_edits3(word)) or [word]) 

    soundex_word = soundex(word) 
    max_candidate = None 
    max_nword = 0 
    for candidate in candidates: 
     if soundex(candidate) == soundex_word and NWORDS.get(candidate) > max_nword: 
      max_candidate = candidate 
    return max_candidate 
+0

嗨,謝謝。但當我仔細觀察時,我意識到問題是別的。檢查我的問題,我編輯了它。 –