Самый простой (наименьшее количество стандартного кода) способ распараллелить цикл Python? - PullRequest
0 голосов
/ 25 мая 2019

У меня есть некоторый код, который выглядит следующим образом:

for photo in photoInfo:
    if not('url' in photo):
        raise Exception("Missing URL: " + str(photo) + " in " + str(photoInfo))
    sizes = getImageSizes(photo['url'])
    photo.update(sizes)

Это может быть неочевидно, но код выполняет сочетание операций ввода-вывода с высокой задержкой (открытие удаленного URL) и умеренной загрузки ЦП.интенсивный процесс (синтаксический анализ изображения и извлечение размера) для каждой фотографии.

Какой самый простой способ распараллелить этот код?

Что я пробовал до сих пор

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

from itertools import product
from multiprocessing import Pool

with Pool(processes=4) as pool:  # assuming Python 3
    pool.starmap(print, product(range(2), range(3), range(4)))

Ответы [ 2 ]

0 голосов
/ 25 мая 2019
from multiprocessing import Pool
import os

def user_defined_function(url):
    #your logic for a single url
    pass

if __name__ == '__main__':
    urls_list = ['u1','u2']
    pool = Pool(os.cpu_count())                         # Create a multiprocessing pool
    pool.map(user_defined_function, urls_list)

это пример кода, вы можете изменить его в соответствии с вашим использованием. Я сопоставлю каждый элемент списка с вашей функцией и выполню ее индивидуально.

0 голосов
/ 25 мая 2019

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

from multiprocessing import Pool

def get_image_size(photo):
    if 'url' not in photo:
        raise Exception("Missing URL: " + str(photo))
    return getImageSizes(photo['url'])

if __name__ == '__main__':
    with Pool() as pool:
        photoInfo = dict(zip(photoInfo, pool.map(get_image_size, photoInfo)))
...