Многопоточность в Python: параллельное сравнение объектов в итераторе - PullRequest
0 голосов
/ 23 октября 2019

Я хотел бы распараллелить скрипт, который возвращает список неэквивалентных объектов. (На практике «объекты» - это графы, и я ищу наборы неизоморфных графов в очень больших наборах графов.)

Вот некоторый псевдокод:

from itertools import combinations
from multiprocessing import Pool

p = Pool(number_of_threads)

def find_nonequivalent_objects(n,m):
    list_of_objects = []
    # LOOP 1: many billions of combinations
    for c in combinations(n,m): 
        new_obj  = generate_object_from_combination(c)
        if not len(list_of_objects)==0:
            compare_to_new_obj = lambda old_obj: check_equivalence(new_obj, 
                                                                   old_obj)
            # MAP 1: a few hundred comparisons
            if not np.any(map(compare_to_new_obj, list_of_objects)):
                list_of_objects = list_of_objects + [new_obj]
        else:
            list_of_objects = [new_obj]

    # return a list of a few hundred objects
    return list_of_objects 

IСначала попытался использовать p.map для MAP 1 (заменив лямбда-функцию на functools.partial), но дополнительные накладные расходы компенсировали ускорение, поэтому общее время выполнения увеличилось. Похоже, что лучший подход будет разделить LOOP 1 на куски. Для этого потребуется что-то вроде этого:

list_of_lists_of_objects = pool.map(LOOP1_function, combinations(n,m))

# compare list_of_objects from different chunks
for i in range(1, number_of_threads):
    for new_obj in list_of_lists_of_objects[i]:
        compare_to_new_obj = lambda old_obj: check_equivalence(new_obj, old_obj)
        if not np.any(map(compare_to_new_obj, list_of_lists_of_objects[0])):
            list_of_lists_of_objects[0] = list_of_lists_of_objects[0] + [new_obj]

list_of_objects = list_of_lists_of_objects[0]

Это приводит меня к двум проблемам:

  1. Насколько я понимаю, использование p.map в LOOP 1 означает, чтоЯ прошу машину создать список itertools.combinations(n,m). Это может привести к проблемам с памятью.

  2. Каждый работник или блок должен иметь свой собственный list_of_objects. Как я могу это сделать?

...