2014-02-14 3 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)) 

И это похоже на заявление for candidate in candidates увеличивает время выполнения. Вы можете легко просмотреть код peter norvig, нажмите 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 для петель. так что это преступник.

Как свести к минимуму это выражение? Может ли itertools.repeat помочь с этим?

+0

Увеличение времени выполнения * по сравнению с тем, что *? –

+1

Попробуйте сначала составить список и посмотрите, улучшится ли это: 'кандидат_new = [кандидат в кандидаты в кандидаты, если soundex (кандидат) == soundex (word)]' – 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

привет, спасибо. но когда я посмотрел внимательно, я понял, что проблема - это что-то еще. проверьте мой вопрос, я его отредактировал. –

Смежные вопросы