dask.bag/dask.delayed for循环之间有什么区别,请为dask中的python并行作业选择更好的方法

dask.bag/dask.delayed for循环之间有什么区别,请为dask中的python并行作业选择更好的方法,python,parallel-processing,dask,Python,Parallel Processing,Dask,环境信息: Python==3.7 Win7 i5-2310:2-cores-4-threads 4GB-memory 达斯基尼: from dask.distributed import Client Client() # Client Scheduler: tcp://127.0.0.1:50723 Dashboard: # http://127.0.0.1:8787/status Cluster Workers: 4 Cores: 4 Memory: 4.20 GB 第一个:

环境信息:

Python==3.7
Win7 i5-2310:2-cores-4-threads 4GB-memory
达斯基尼:


from dask.distributed import Client

Client()

# Client Scheduler: tcp://127.0.0.1:50723 Dashboard:
# http://127.0.0.1:8787/status Cluster Workers: 4 Cores: 4 Memory: 4.20 GB

第一个: 带For循环的延迟功能:

@dask.delayed
def teststr(x,y):
    return x+y


rt=[]
for i in range(1000):
    rt.append(teststr(str(i),str(i+1)) )
rt = dask.compute(*rt)

它显示
墙壁时间:3.23秒

第二个: 带地图功能的基于列表的行李:

import dask.bag as db

b=db.from_sequence([(str(i),str(i+1)) for i in range(1000)])

def teststr2(x,y):
    return x+y

%%time
rt2=b.map(lambda x:teststr2(x[0],x[1])).compute()
它显示
墙时间:899毫秒
forloop-one比bag-one需要更多的时间,而且它需要大量的磁盘IO(可能是虚拟内存)

我没有检查如果我更改dask.client配置(线程与进程)、不同的任务(整数函数与字符串函数与没有GIL的函数、数据库IO与磁盘IO)或更大的对象(在执行某些数据分析工作时使用大数据帧或Numpy)会发生什么

如何为dask中的python并行作业选择更好的方式。虽然我得到相同的输出,但有时它需要太多的计算时间。一定有一些规则帮助我


我希望这可能是一个备忘单,它告诉我根据系统环境、任务类型或其他内容组织代码的最佳方法。

这两个选项之间的一个主要区别是任务的数量。您可以执行
len(thing.dask)
快速查看计算给定dask对象、延迟对象或包所需的图形

>>> rt2=b.map(lambda x:teststr2(x[0],x[1]))
>>> len(rt2.dask)
200

>>> rt=[]
>>> for i in range(1000):
...     rt.append(teststr(str(i),str(i+1)) )
>>> sum(len(t.dask) for t in rt)
1000

因此,包中的任务数量减少了五倍,这是因为包对输入(也称为分区)成批进行计算。由于您请求的计算功能发生得非常快,因此总时间完全由每个任务的开销和将任务图发送到调度程序所需的时间决定。

我选中了默认值
b.npartitions=100
。那么什么是nPartition呢?这是否意味着对于1000个作业,运行100个批次,每个批次包含10个作业?既然我们有一个4线程内核的CPU,为什么不每个4个作业呢?简单地说:这就是bag为您做的。是的,每个分区都是项的集合,当您运行
map
时,这些项将转换为一组函数调用(我不称它们为“作业”)。理想情况下,选择分区大小是为了使每个任务都有足够的工作要做,与开销相比较小,而不是太大以至于分区本身会造成内存压力。