在本文中,我们将了解如何通过使用 Joblib 模块在 Python 中并行执行代码来大幅减少大型代码的执行时间。
Joblib是一个用于Python的开源库,它提供了一些用于并行计算和内存映射的工具,旨在提高科学计算和数据分析的效率。
Python 中的 Joblib 模块特别用于使用 Pipelines 并行执行任务,而不是一个接一个地顺序执行任务。Joblib 模块允许用户通过利用设备中存在的所有内核来充分发挥设备的潜力,使过程尽可能快。Joblib还允许用户通过将结果存储在缓存中来使用上次缓存的结果,这样任何进程的执行速度都可以大大降低。然后我们还可以同时并行运行多个作业,尽管可以并行运行的作业数量受到当时 CPU 中可用的空闲核心数量的限制。
Joblib 模块不仅可用于从设备上的任何位置转储和加载不同的结果、数据集、模型等,例如 Pickle 模块,而且我们还可以简单地传递路径和文件名来加载或转储它。Joblib 还提供了一种压缩大型数据集的方法,以便于加载和操作。Joblib 模块中可用的不同压缩方法有 Zlib 和 LZ4,在转储数据集时,我们需要将压缩类型作为 Joblib 模块转储方法的参数。文件将以我们使用的压缩扩展名存储,Zlib 压缩为 .zlib,Lz4 压缩为 .zl4。
主要特点:
总的来说,Joblib是一个功能强大的Python库,它提供了一系列工具和技术,使用户能够更高效地处理大规模数据集和复杂计算任务。通过并行计算、内存映射和函数缓存等功能,Joblib帮助用户克服了内存限制问题,提高了计算速度和数据访问速度,从而加速了科学计算和数据分析的过程。
pip install joblib
首先,我们将从 joblib 模块和 time 模块导入所需的类。
import time
from joblib import Parallel,delayed
import math
t1 = time.time()
# Normal
r = [math.factorial(int(math.sqrt(i**3))) for i in range(100,1000)]
t2 = time.time()
print(t2-t1)
输出
5.053828239440918
这里我们导入 joblib 模块的并行类和延迟类,然后首先我们将检查该操作通常需要多少时间来执行。在这里,我尝试首先找出 100 到 999 之间每个数字的立方的平方根,然后找到它们的阶乘,用户可以尝试任何其他操作,但使其尽可能复杂以获得更好的结果。
现在我们将使用 difflib 模块的并行和延迟函数来尽可能减少这个时间。
两核心
使用并行功能,我们将使用 2 个核心来执行此代码并延迟阶乘函数。
import time
from joblib import Parallel,delayed
import math
t1 = time.time()
# 2 Core
r1 = Parallel(n_jobs=2)(delayed(math.factorial) (int(math.sqrt(i**3))) for i in range(100,1000))
t2 = time.time()
print(t2-t1)
输出
3.4186928272247314
这里,Parallel 函数接受一个参数 n_jobs,我们必须在其中传递我们想要使用的核心数量,或者我们将使用多少个管道来并行执行代码。之后,我们延迟 math.factorial 函数,以便它与每个管道并行工作,然后我们传递主操作。请记住始终在延迟内使用最外部的函数,对于本示例,如果我们在延迟内使用 math.sqrt 那么这不会给出更好的结果,因为我们正在使用 sqrt 的结果来做其他事情。
三核心
import time
from joblib import Parallel,delayed
import math
t1 = time.time()
# 3 Core
r1 = Parallel(n_jobs=3)(delayed(math.factorial) (int(math.sqrt(i**3))) for i in range(100,1000))
t2 = time.time()
print(t2-t1)
输出
3.0704777240753174
四核心
import time
from joblib import Parallel,delayed
import math
t1 = time.time()
# 4 Core
r1 = Parallel(n_jobs=4)(delayed(math.factorial) (int(math.sqrt(i**3))) for i in range(100,1000))
t2 = time.time()
print(t2-t1)
输出
2.864224910736084
使用所有核心
现在,如果有人不知道他们的设备有多少个核心,但想使用尽可能多的核心,那么他们将提供 -1 作为 n_jobs 参数的值。
import time
from joblib import Parallel,delayed
import math
t1 = time.time()
# Max Core
r1 = Parallel(n_jobs=-1)(delayed(math.factorial) (int(math.sqrt(i**3))) for i in range(100,1000))
t2 = time.time()
print(t2-t1)
输出
2.7631096839904785