Многопроцессорная обработка медленнее, чем последовательная, при обработке текста слово за словом - PullRequest
0 голосов
/ 04 июля 2018

Мне нужно обрабатывать текстовые слова. Поскольку последовательная программа, которую я написал, очень медленная, я попытался закодировать ее, используя многопроцессорную библиотеку. Я обнаружил, что многопроцессорное программное обеспечение намного медленнее, чем последовательное. Я что-то упускаю в коде при использовании функции Pool? Функция do_something выполняет много форсов и ifs.

Последовательный код:

class Text():
    def do_something(self, word):
        ....
        # Computational heavy code
        ....
        return new_word
....
new_text = []
for sentence in text:
    new_sentence = []
    for word in sentence:
        ....
        new_word = Text().do_something(word)
        new_sentence += new_word
    new_text.append(new_sentence)
print(new_text)

Многопроцессный код:

class Text():
    def do_something(self, word):
        ....
        # Computational heavy code
        ....
        return new_word

    def do_word(self, word):
        ....
        if len(word) > 2:
            return self.do_something(word).split('$')
        else:
            return ['NONE']

    def do_text(self, text):
        new_text = []
        pool = Pool(processes = cpu_count())   

        for sentence in text:
            new_text.append( [item for sublist in pool.map(self.do_word, sentence.split()) for item in sublist if item != 'NONE'] )
        return new_text

if __name__ == "__main__":
    ....
    print(Text().text(file))

Редактировать

По предложению Панагиотиса Канавоса, я попытался реализовать многопоточность вместо многопроцессорной. Однако при выполнении приведенного ниже кода машина, кажется, использует только одно ядро ​​(загрузка процессора составляет около 25%, в то время как у меня 4-ядерный процессор). Скорость, по-видимому, та же самая, что и при использовании последовательного кода (который также использует процессор на 25%).

from multiprocessing.dummy import Pool as ThreadPool 

class Text():
    def do_something(self, word):
        ....
        # Computational heavy code
        ....
        return new_word

    def do_word(self, word):
        ....
        if len(word) > 2:
            return self.do_something(word).split('$')
        else:
            return ['NONE']

    def do_text(self, text):
        new_text = []
        pool = ThreadPool(processes = cpu_count())   

        for sentence in text:
            new_text.append( [item for sublist in pool.map(self.do_word, sentence.split()) for item in sublist if item != 'NONE'] )
        return new_text

if __name__ == "__main__":
    ....
    print(Text().text(file))
...