Я б не називав concurrent.futures
більш «просунутим» - це простіший інтерфейс, який працює майже однаково, незалежно від того, використовуєте ви декілька потоків або декілька процесів в якості основної прихилки паралелізації.
Таким чином, як і практично у всіх випадках «простішого інтерфейсу», задіяні такі ж компроміси: він має більш дрібну криву навчання, значною мірою лише тому, що є так багато менш доступного для вивчення; але, оскільки він пропонує менше варіантів, це може врешті зривати вас тим, що багатші інтерфейси не стануть.
Що стосується завдань, пов'язаних з процесором, це занадто недостатньо вказано, щоб сказати, що це має велике значення. Для завдань, пов'язаних з процесором під CPython, вам потрібно кілька процесів, а не декілька потоків, щоб мати шанс отримати швидкість. Але кількість (якщо така є) швидкості, яку ви отримаєте, залежить від деталей вашого обладнання, вашої ОС і, особливо, від того, наскільки міжпроцесорне спілкування потребує ваших конкретних завдань. Під обкладинками всі мішки міжпроцесорної паралелізації паралелізуються одними і тими ж примітивами ОС - API високого рівня, який ви використовуєте, щоб отримати на них, не є основним фактором швидкості нижньої лінії.
Правка: приклад
Ось кінцевий код, показаний у статті, на яку ви посилаєтесь, але я додаю заяву про імпорт, необхідну для роботи:
from concurrent.futures import ProcessPoolExecutor
def pool_factorizer_map(nums, nprocs):
# Let the executor divide the work among processes by using 'map'.
with ProcessPoolExecutor(max_workers=nprocs) as executor:
return {num:factors for num, factors in
zip(nums,
executor.map(factorize_naive, nums))}
Ось саме те, що використовується multiprocessing
замість цього:
import multiprocessing as mp
def mp_factorizer_map(nums, nprocs):
with mp.Pool(nprocs) as pool:
return {num:factors for num, factors in
zip(nums,
pool.map(factorize_naive, nums))}
Зауважте, що можливість використання multiprocessing.Pool
об'єктів як менеджерів контексту була додана в Python 3.3.
З яким легше працювати? LOL ;-) Вони по суті однакові.
Одна відмінність полягає в тому, що Pool
підтримується так багато різних способів робити речі, що ви можете не усвідомлювати, наскільки це легко, доки ви не піднялися зовсім на криву навчання.
Знову ж таки, всі ці різні способи є і силою, і слабкістю. Вони сильні, оскільки в деяких ситуаціях може знадобитися гнучкість. Вони слабкі, оскільки "бажано лише один очевидний спосіб зробити це". Проект, який дотримується виключно (якщо це можливо) concurrent.futures
, мабуть, буде простішим у підтримці в довгостроковій перспективі, через відсутність безкоштовної новизни в тому, як можна використовувати його мінімальний API.