Для большинства проблем параллельные вычисления действительно могут увеличить скорость вычислений. По мере увеличения вычислительной мощности ПК мы можем просто увеличить объем вычислений, запустив параллельный код на нашем собственном ПК. Joblib - это такой пакет, который может просто превратить наш код Python в режим параллельных вычислений и, конечно же, увеличить скорость вычислений.
Joblib - это набор инструментов для облегчения конвейерной обработки в Python. Особенно:
- прозрачное кэширование функций на диске и ленивая переоценка (шаблон Memoize)
простые простые параллельные вычисления - Joblib оптимизирован, чтобы быть быстрым и надежным, в частности, с большими данными, и имеет определенные оптимизации для массивов numpy.
Здесь мы используем простой пример, чтобы продемонстрировать функциональность параллельных вычислений. Мы определяем простую функцию my_fun
с одним параметром i
. Эта функция подождет 1 секунду, а затем вычислит квадратный корень из i**2
.
from joblib import Parallel, delayed import time, math
def my_fun(i): """ We define a simple function here. """ time.sleep(1) return math.sqrt(i**2)
Здесь мы устанавливаем общую итерацию равной 10. Мы используем функцию time.time()
для вычисления my_fun()
времени выполнения. Используя простой цикл for, мы можем получить время вычисления около 10 секунд.
num = 10 start = time.time() for i in range(num): my_fun(i)
end = time.time()
print('{:.4f} s'.format(end-start))
10.0387 s
С помощью функций Parallel
и delayed
от Joblib мы можем просто настроить параллельный запуск функции my_fun()
. n_jobs
- количество параллельных заданий, и здесь мы установили его равным 2
. i
- входной параметр функции my_fun()
, и мы хотим выполнить 10 итераций. Неудивительно, что два параллельных задания дают мне примерно половину исходного времени выполнения цикла, то есть около 5 секунд.
start = time.time() # n_jobs is the number of parallel jobs Parallel(n_jobs=2)(delayed(my_fun)(i) for i in range(num)) end = time.time() print('{:.4f} s'.format(end-start))
5.6560 s
Это так просто! Что, если у нас есть более одного параметра в наших функциях? Это тоже очень просто. Давайте определим новую функцию с двумя параметрами my_fun_2p(i, j)
.
def my_fun_2p(i, j): """ We define a simple function with two parameters. """ time.sleep(1) return math.sqrt(i**j)
j_num = 3 num = 10 start = time.time() for i in range(num): for j in range(j_num): my_fun_2p(i, j)
end = time.time() print('{:.4f} s'.format(end-start))
30.0778 s
start = time.time() # n_jobs is the number of parallel jobs Parallel(n_jobs=2)(delayed(my_fun_2p)(i, j) for i in range(num) for j in range(j_num)) end = time.time() print('{:.4f} s'.format(end-start))
15.0622 s
Помимо функциональности параллельных вычислений, Joblib также имеет следующие особенности:
- Прозрачное и быстрое кэширование выходного значения на диске: функция memoize или make-like для функций Python, которая хорошо работает для произвольных объектов Python, включая очень большие массивы numpy.
- Быстрая сжатая стойкость: замена pickle для эффективной работы с объектами Python, содержащими большие данные (joblib.dump и joblib.load).
Более подробную информацию можно найти на официальном сайте Joblib.
Другие руководства и статьи можно найти в моем блоге Измерение пространства и на моем канале YouTube.