dask:client.persist 和 client.compute 之间的差异

dask: difference between client.persist and client.compute

我对 client.persist()client.compute() 之间的区别感到困惑(在某些情况下)似乎都开始了我的计算和 return 异步对象,但不在我的计算中简单示例:

在这个例子中

from dask.distributed import Client
from dask import delayed
client = Client()

def f(*args):
    return args

result = [delayed(f)(x) for x in range(1000)]

x1 = client.compute(result)
x2 = client.persist(result)

这里 x1x2 是不同的,但在一个不那么琐碎的计算中 result 也是一个 Delayed 对象的列表,使用 client.persist(result) 开始计算就像 client.compute(result) 一样。

相关文档页面在这里:http://distributed.readthedocs.io/en/latest/manage-computation.html#dask-collections-to-futures

正如您所说,Client.computeClient.persist 都采用惰性 Dask 集合并在集群上启动它们 运行ning。他们的不同之处在于 return.

  1. Client.persist returns 每个 dask 集合的副本及其 previously-lazy 计算现在提交给集群上的 运行。这些集合的任务图现在只指向当前 运行ning 个 Future 对象。

    所以如果你坚持一个有 100 个分区的 dask 数据帧,你会回来 一个有 100 个分区的 dask 数据框,每个分区指向 集群上当前 运行ning 的未来。

  2. Client.compute return 每个集合都有一个 Future。这个 future 指的是在一个 worker 上收集的单个 Python 对象结果。这通常用于小的结果。

    因此,如果您计算一个包含 100 个分区的 dask.dataframe,您会得到一个指向单个 Pandas 数据帧的 Future,该数据帧包含所有数据

更实用的是,我建议当你的结果很大并且需要分布在多台计算机上时使用 persist,而当你的结果很小并且你只想在一台计算机上使用它时使用计算。

在实践中,我很少使用 Client.compute,而是更喜欢使用 persist 进行中间阶段和 dask.compute 来下拉最终结果。

df = dd.read_csv('...')
df = df[df.name == 'alice']
df = df.persist()  # compute up to here, keep results in memory

>>> df.value.max().compute()
100

>>> df.value.min().compute()
0

使用延迟时

无论如何,延迟对象只有一个 "partition",因此计算和持久化更容易互换。 Persist 会给你一个惰性的 dask.delayed 对象,而 compute 会给你一个即时的 Future 对象。