Полезные советы по достижению максимальной производительности в Python с помощью библиотеки многопроцессорности

Обзор

Иногда Python работает медленно. По умолчанию Python работает в одном потоке. Чтобы увеличить скорость обработки в Python, код может выполняться в нескольких процессах. Такое распараллеливание позволяет распределять работу по всем ядрам ЦП. При выполнении на нескольких ядрах длительные задания можно разбить на более мелкие управляемые блоки. После того, как отдельные задания выполняются параллельно, возвращаются результаты, а время обработки резко сокращается. Мультиобработка в Python эффективна для ускорения времени обработки долго выполняемых функций.

Мультиобработка

Python имеет встроенную многопроцессорность. С помощью простого оператора импорта:

import multiprocessing

у нас есть возможность запускать разные функции параллельно. Этот пакет содержит несколько стратегий повышения скорости за счет параллельного выполнения функций. В этом посте мы расскажем о некоторых быстрых и простых реализациях с использованием multiprocessing для ускорения длительного кода.

Бассейн

multiprocessing включает класс Pool, который позволяет создавать пул рабочих. После выделения пула у нас появляется группа рабочих потоков, которые могут обрабатываться параллельно. Обычно это выглядит так:

number_of_workers = 10
with Pool(number_of_workers) as p:
    # Do something with pool here

Теперь, когда пул выделен, работникам можно давать задания.

карта

Теперь, когда пул выделен, работа может выполняться параллельно. Используя map, мы можем разделить задание на несколько процессов одновременно. В приведенном ниже примере мы используем многопроцессорную обработку, чтобы возвести в квадрат и параллельно распечатать большой массив чисел.

def do_something(number):
    return number ** 2
array_of_numbers = [x for x in range(0, 100000000000)]
with Pool(number_of_workers) as p:
    print(p.map(do_something, array_of_numbers))

Если бы это нужно было делать последовательно (без распараллеливания), это заняло бы довольно много времени. Взяв эту работу и разделив ее на части, мы можем разделить ее между разными ядрами ЦП, чтобы ускорить задачу.

Под капотом map берет текущий процесс Python, обрабатывает его и отправляет другому ядру ЦП. Иногда этот нюанс приводит к проблемам. Например, если текущий размер процесса в памяти составляет 4 ГБ, а код использует Pool(4) на четырехъядерном компьютере, этот процесс Python объемом 4 ГБ будет обработан и отправлен 4 рабочим. Это может увеличить использование памяти до 4 ГБ * 4 рабочих = 16 ГБ.

Имап

Более оптимизированный метод - imap. Этот метод не дублирует пространство памяти исходного процесса Python для разных рабочих процессов. imap возвращает итератор вместо завершенной последовательности, таким образом используя меньше памяти.

def do_something(number):
    return number ** 2
array_of_numbers = [x for x in range(0, 100000000000)]
with Pool(number_of_workers) as p:
    print(p.imap(do_something, array_of_numbers))

Результат использования imap идентичен map, но уменьшает использование памяти.

Следует отметить, что imap и map могут передавать только один параметр функции, которая будет распараллелена.

Звездная карта

Другая функция starmap идентична map по функциональности с точки зрения использования памяти. Разница в том, что starmap допускает несколько аргументов.

def do_something(number, another_number):
    return number ** 2 + another_number ** 2)
array_of_number_tuple = [(x, x + 1) for x in range(0, 100000000000)]
with Pool(number_of_workers) as p:
    print(p.starmap(do_something, array_of_number_tuple))

В приведенном выше примере кода мы показываем, чем starmap отличается от map и imap. Вместо одного параметра функции, которая выполняется параллельно, передаются несколько параметров.

Заключение

Пакет Python multiprocessing позволяет быстрее выполнять длительные задания. Существуют более сложные способы использования пакета, которые не описаны в этом посте, о которых можно прочитать далее на странице документации Python. Используя инструменты из библиотеки multiprocessing, вы можете сократить время обработки с дней до часов.

Наконец, если использование Python увлекательно и получение максимальной отдачи от вашего кода кажется забавным, мы всегда ищем опытных разработчиков Python в Apteo. Не стесняйтесь обращаться по адресу [email protected]