一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情。
今天随着互联网不断发展,每天都在产生海量的数据,如何在这样大规模的数据上进行计算成为我们需要面临的挑战。对于 python 个人认为对于多进程编程实现不是那么容易的一门语言,一个方便好用,且可以和一些老牌科学计算库、例如 numpy、pandas 这样库很好结合的可以实现扩展平行计算库就显得非常重要,那么今天 Dask 出现就填补了这个空白,为以上问题提出解决方案。
今天我们简单地聊一聊这个 Dask 平行计算库,如果觉得对你有所帮助、请给我点赞。如果想要深入了解这个库,可以在评论区留言,随后我会系统地带来更详细、更具体关于如何这个库的使用的分享。
首先我们来创建两个函数、分别是对输入自增 1 的 inc 和一个对输入两个变量进行求和的 add 在函数内部添加了 sleep 来模拟耗时。
from time import sleep
def inc(x):
sleep(1)
return x + 1
def add(x,y):
sleep(1)
return x + y
%%time
x = inc(1)
y = inc(2)
z = add(x,y)
%%time 是 jupyter notebook 提供一个用于计算耗时的一个函数,运行这块代码后,可以在输出查看运行代码一些耗时信息,这里我们关注 Wall time 就可以,这里是 3 秒钟,和我们上面对于程序的设计是 match 的。
CPU times: user 1.56 ms, sys: 346 µs, total: 1.91 ms
Wall time: 3 s
好,现在轮到我们今天主角登场了,这就是 Dask,我们先通过 dask 提供 delayed 将函数进行转换
from dask import delayed
我们希望在上面计算中对于 x 和 y 增量计算是同时进行的,因为他们之间并不存在任何依赖关系。我们可以通过注解方式来将两个函数转换,也就是
@delayed
def inc(x):
sleep(1)
return x + 1
@delayed
def add(x,y):
sleep(1)
return x + y
%%time
x = delayed(inc)(1)
y = delayed(inc)(2)
z = delayed(add)(x,y)
CPU times: user 525 µs, sys: 113 µs, total: 638 µs
Wall time: 479 µs
我们发现运行上面代码的时间很快,这是因为上面代码仅是对于函数进行包裹,并没有进行任何计算。这里返回的是 delayed 对象,当我们调用 delayed 对象的 compute() 方法时,才开始计算,这时大家不难发现这里时间已经从上面 3秒变为了 2秒。
%%time
z.compute()
CPU times: user 2.64 ms, sys: 3.78 ms, total: 6.42 ms
Wall time: 2.01 s
对于 z 对象 delayed 对象,z 对象是以延迟执行对象,所谓延迟就是只有在调用其 compute 方法时候才会开始计算,z 对象是将如何通过输入 x y 来计算出输出 z 用一个计算图来构建出计算图,也就是建立函数在这个计算过程之间的关系,可以同一个图来表示各个函数之间依赖关系,可以调用 z 的 visualize 方法来可视化
z.visualize()
通过这张图我们不难看出为什么通过 dask 参与计算是从 3秒缩减到了 2秒,这里讲 inc 函数计算不再优先次序了,而是一个并行计算。
data = [1,2,3,4,5,6,7,8]
我们创建一个数组,然后利用一个 for 循环对每一个元素进行自增 1 然后添加到一个数组 results 后对每一个元素自增后组成数组进行求和
%%time
def inc(x):
sleep(1)
return x + 1
results = []
for x in data:
y = inc(x)
results.append(y)
total = sum(results)
CPU times: user 1.69 ms, sys: 0 ns, total: 1.69 ms
Wall time: 8.01 s
从时间来看,对于每一个 inc 都会耗时 1秒,一共耗时 8 秒
%%time
results = []
for x in data:
y = delayed(inc)(x)
results.append(y)
total = delayed(sum)(results)
CPU times: user 0 ns, sys: 2.39 ms, total: 2.39 ms
Wall time: 3.88 ms
total.visualize()
%%time
total.compute()
CPU times: user 3.65 ms, sys: 666 µs, total: 4.31 ms
Wall time: 2.01 s