Распараллеливание создание списка списков с использованием многопроцессора

#python #python-3.x #multiprocessing #multiprocessor

Вопрос:

Я создаю список списков, используя функцию, которая занимает много времени для вычисления каждого из элементов списка. Поскольку это замедляет весь мой процесс, я пытаюсь ускорить его с помощью multiprocessing библиотеки на python.

Однако, когда я пытаюсь использовать многопроцессор, это заставляет мой код работать еще медленнее. Есть идеи, почему это происходит?

 import multiprocessing
import time

# arbitrary F function for a reproducible example
# The actual function is more complicated
def f(a, b):
    for i in range(100000):
        a = True
    return [a * b, a   b]


if __name__ == '__main__':
    G = [1, 2]
    l = [t for t in range(6000)]

    t1 = time.time()
    my_list1 = [[f(l[x], G[i])[0] for i in range(len(G))] for x in range(len(l))]
    t2 = time.time()
    print("Original: ", t2 - t1)

    pool = multiprocessing.Pool(processes=multiprocessing.cpu_count())
    t3 = time.time()
    my_list2 = [[pool.apply(f, args=(l[x], G[i]))[0] for i in range(len(G))] for x in range(len(l))]
    t4 = time.time()
    pool.close()
    print("Parallelized: ", t4 - t3)
 

пример вывода:

 Original:  29.832287073135376
Parallelized:  33.75640296936035
 

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

Комментарии:

1. pool.apply не запускается асинхронно, блокируется до тех пор, пока результат не будет готов. Вы должны использовать один из асинхронных вариантов, а затем построить результат, когда все они будут выполнены

2. запуск нескольких процессов съедает время

3. Как уже отмечалось, ваше выполнение по-прежнему является последовательным. apply_async-это неблокирующая версия apply, но затем ваш синтаксис меняется. Ваша дополнительная медлительность в основном вызвана тем, что ваши возвращаемые объекты огромны. Многопроцессорная обработка обрабатывает поступающие/исходящие данные в виде очередей, и они выполняются медленно. Когда вы вернете огромный массив, это займет время. Либо примите время, необходимое для этого без многопроцессорной обработки, либо перепроектируйте свой код так, чтобы он выполнял все, что ему нужно, в подпроцессах, чтобы вам не нужно было передавать так много данных между процессами.