Как я могу заставить этот код работать быстрее? (поиск большого текста для больших слов) - PullRequest
3 голосов
/ 23 апреля 2011

в Python, я создал генератор текста, который действует на определенные параметры, но мой код - в большинстве случаев - медленный и работает ниже моих ожиданий. Я ожидаю одно предложение каждые 3-4 минуты, но оно не соответствует, если база данных, на которой он работает, большая - я использую корпус из 18 книг проекта Гутенберга, и я создам свой собственный корпус и добавлю дополнительные книги, чтобы производительность была жизненно важной. Алгоритм и реализация приведены ниже:

АЛГОРИТМ

1- Введите триггерное предложение - только один раз, в начале программы -

2- Получить самое длинное слово в предложении триггера

3- Найти все предложения корпуса, содержащие слово на шаге 2

4- Случайно выберите одно из этих предложений

5- Получите предложение (названное sentA для разрешения неоднозначности в описании), следующее за предложением, выбранным на шаге 4 - до тех пор, пока sentA длиннее 40 символов -

6 - перейти к шагу 2, теперь триггерное предложение - это sendA шага 5

РЕАЛИЗАЦИЯ

from nltk.corpus import gutenberg
from random import choice

triggerSentence = raw_input("Please enter the trigger sentence:")#get input sentence from user

previousLongestWord = ""

listOfSents = gutenberg.sents()
listOfWords = gutenberg.words()
corpusSentences = [] #all sentences in the related corpus

sentenceAppender = ""

longestWord = ""

#this function is not mine, code courtesy of Dave Kirby, found on the internet about sorting list without duplication speed tricks
def arraySorter(seq):
    seen = set()
    return [x for x in seq if x not in seen and not seen.add(x)]


def findLongestWord(longestWord):
    if(listOfWords.count(longestWord) == 1 or longestWord.upper() == previousLongestWord.upper()):
        longestWord = sortedSetOfValidWords[-2]
        if(listOfWords.count(longestWord) == 1):
            longestWord = sortedSetOfValidWords[-3]


doappend = corpusSentences.append

def appending():

    for mysentence in listOfSents: #sentences are organized into array so they can actually be read word by word.
        sentenceAppender = " ".join(mysentence)
        doappend(sentenceAppender)


appending()
sentencesContainingLongestWord = []

def getSentence(longestWord, sentencesContainingLongestWord):


    for sentence in corpusSentences:
        if sentence.count(longestWord):#if the sentence contains the longest target string, push it into the sentencesContainingLongestWord list
            sentencesContainingLongestWord.append(sentence)


def lengthCheck(sentenceIndex, triggerSentence, sentencesContainingLongestWord):

    while(len(corpusSentences[sentenceIndex + 1]) < 40):#in case the next sentence is shorter than 40 characters, pick another trigger sentence
        sentencesContainingLongestWord.remove(triggerSentence)
        triggerSentence = choice(sentencesContainingLongestWord)
        sentenceIndex = corpusSentences.index(triggerSentence)

while len(triggerSentence) > 0: #run the loop as long as you get a trigger sentence

    sentencesContainingLongestWord = []#all the sentences that include the longest word are to be inserted into this set

    setOfValidWords = [] #set for words in a sentence that exists in a corpus                    

    split_str = triggerSentence.split()#split the sentence into words

    setOfValidWords = [word for word in split_str if listOfWords.count(word)]

    sortedSetOfValidWords = arraySorter(sorted(setOfValidWords, key = len))

    longestWord = sortedSetOfValidWords[-1]

    findLongestWord(longestWord)

    previousLongestWord = longestWord

    getSentence(longestWord, sentencesContainingLongestWord)

    triggerSentence = choice(sentencesContainingLongestWord)

    sentenceIndex = corpusSentences.index(triggerSentence)

    lengthCheck(sentenceIndex, triggerSentence, sentencesContainingLongestWord)

    triggerSentence = corpusSentences[sentenceIndex + 1]#get the sentence that is next to the previous trigger sentence

    print triggerSentence
    print "\n"

    corpusSentences.remove(triggerSentence)#in order to view the sentence index numbers, you can remove this one so index numbers are concurrent with actual gutenberg numbers


print "End of session, please rerun the program"
#initiated once the while loop exits, so that the program ends without errors

Компьютер, на котором я запускаю код, немного стар, двухъядерный процессор был куплен в феврале 2006 года, а 2x512 оперативной памяти был куплен в сентябре 2004 года, поэтому я не уверен, что моя реализация плохая или аппаратное обеспечение причина медленного времени выполнения. Любые идеи о том, как я могу спасти это от его опасной формы? Заранее спасибо.

Ответы [ 2 ]

4 голосов
/ 23 апреля 2011

Я думаю, что мой первый совет должен быть: подумайте о том, что делают ваши подпрограммы, и убедитесь, что название описывает это.В настоящее время у вас есть такие вещи, как:

  • arraySorter, которые не имеют отношения ни к массивам , ни к сортировке (это реализация nub )
  • findLongestWord, который считает вещи или отбирает слова по критериям, которых нет в описании алгоритма, но в итоге ничего не делает, потому что longestWord является локальной переменной (как бы аргументом)
  • getSentence, которая добавляетпроизвольное количество предложений в списке
  • appending, которое звучит так, как будто оно может быть проверкой состояния, но работает только через побочные эффекты
  • значительная путаница между локальными и глобальными переменными, например, глобальнойпеременная sentenceAppender никогда не используется и не является действующим лицом (например, функцией), как следует из названия

Для самой задачи вам действительно нужны индексы.Индексирование каждого слова может быть излишним - технически вам нужны только записи индекса для слов, которые встречаются как самое длинное слово в предложении.Словари - это ваш основной инструмент, а второй - списки.Когда у вас есть эти индексы, для поиска случайного предложения, содержащего любое данное слово, требуется только поиск по словарю, random.choice и поиск по списку.Возможно, несколько поисков по списку, учитывая ограничение длины предложения.

Этот пример должен доказать хороший объектный урок, что современное оборудование или оптимизаторы, такие как Psyco, не решают алгоритмических задач.

1 голос
/ 23 апреля 2011

Может быть Псико ускоряет казнь?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...