Почему в многопроцессорной обработке добавить список медленнее - PullRequest
0 голосов
/ 16 октября 2018

Во время тестирования выясняется, что MP-метод работает немного медленнее

def eat_time(j):
    result = []
    for j in range(10**4):
        a = 0
        for i in range(1000):
            a += 101
            result.append(a)
    return result

if __name__ == '__main__':
    #MP method
    t = time.time()
    pool = Pool()
    result = []
    data = pool.map(eat_time, [i for i in range(5)])
    for d in data:
        result += d
    print(time.time()-t) #11s for my computer

    #Normal method
    t = time.time()
    integers = []
    for i in range(5):
        integers += eat_time(i)
    print(time.time()-t) #8s for my computer

Однако, если мне не требуется агрегировать данные, изменив eat_time() на

def eat_time(j):
    result = []
    for j in range(10**4):
        a = 0
        for i in range(1000):
            a += 101
            #result.append(a)
    return result

Время MP намного быстрее, и теперь для моего компьютера просто запустите 3 с , в то время как обычный метод все еще занимает 8 с . (Как и ожидалось)

Мне кажется странным, что result объявлен индивидуально в method, я не ожидаю, что добавление полностью разрушит MP.

Могу ли я узнать, есть ли правильный способ сделать это?И почему MP медленнее при добавлении?


Отредактировано для комментария

Спасибо за @torek и @akhavro прояснить вопрос.

Да, я понимаю, что создание процесса занимает много времени, поэтому возникла проблема.

На самом деле исходный код выводит цикл for наружу и снова и снова вызывает простой метод, он значительно быстрее обычного методамного заданий (в моем случае более 10 ** 6 звонков).

Поэтому я перехожу на код внутри и усложняю метод.Перемещая for j in range(10**4): эту строку в eat_time().

Но кажется, что усложнение кода приводит к задержке связи из-за большего размера данных.

Так что, вероятно, ответ - это не способ решитьэто.

1 Ответ

0 голосов
/ 16 октября 2018

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

Когда вы возвращаете свой результат от Pool работника, на практике это реализуется как очередь из многопроцессорной обработки.Это работает, но это не чудодейственный исполнитель, безусловно, намного медленнее, чем просто манипулирование структурами в памяти.Когда вы возвращаете много данных, очередь должна передавать много.

Нет простого обходного пути.Вы можете попробовать совместную память, но мне лично это не нравится из-за дополнительной сложности.Лучшим способом было бы перепроектировать ваше приложение так, чтобы ему не нужно было передавать много данных между процессами.Например, можно ли будет обрабатывать данные на вашем рабочем месте в дальнейшем, чтобы вам не нужно было возвращать все это, а только обработанное подмножество?

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