Я пытаюсь распараллелить некоторый код Python с помощью процессов и concurrent.futures
. Похоже, я могу выполнять функцию несколько раз в parrallel либо по звонкам submitting, а затем звонить по фьючерсам Future.result()
или с помощью Executor.map()
.
Мне интересно, является ли последний просто синтаксическим сахаром для первого и если есть какая-то разница в производительности. Из документации не видно сразу.Понимание concurrent.futures.Executor.map()
ответ
Это позволит вам выполнять функцию несколько раз одновременно, а не выполнять параллельное выполнение.
Производительность, я недавно обнаружил, что ProcessPoolExecutor.submit()
и ProcessPoolExecutor.map()
потребляют столько же времени на выполнение той же задачи. Примечание: .submit()
возвращает будущий объект (назовем его f), и вам нужно использовать опцию f.result
, чтобы увидеть его результат. С другой стороны, .map()
напрямую возвращает итератор.
При преобразовании их результатов в упорядоченный список с использованием отсортированного метода я обнаружил, что время вычисления всего кода .map()
может быть быстрее, чем весь код .submit()
в определенных сценариях.
При преобразовании их результатов в неупорядоченный список, используя метод списка, время вычисления всех кодов .submit()
и .map()
те же. Кроме того, эти коды выполняются быстрее, чем коды, используя отсортированный метод.
Вы можете прочитать информацию в моем answer. Там я также поделился своими кодами, где вы можете увидеть, как они работают. Надеюсь, они могут вам помочь.
Я не использовал ThreadPoolExecutor
, поэтому не могу прокомментировать. Тем не менее, я прочитал, что они реализованы так же, как и ProcessPoolExecutor
, и они больше подходят для задач привязки ввода-вывода вместо задач с привязкой к ЦП. Вам нужно указать аргумент max_workers
, то есть максимальное количество потоков, тогда как в ProcessPoolExecutor
max_workers
является необязательным аргументом, который по умолчанию соответствует количеству процессоров, возвращаемых os.cpu_count()
.