我有一个配置单元格式和活泼压缩的实木复合地板文件。它适合内存,并且pandas.info提供以下数据。
拼花文件中每组的行数仅为10万
>>> df.info()
<class 'pandas.core.frame.DataFrame'>
Index: 21547746 entries, YyO+tlZtAXYXoZhNr3Vg3+dfVQvrBVGO8j1mfqe4ZHc= to oE4y2wK5E7OR8zyrCHeW02uTeI6wTwT4QTApEVBNEdM=
Data columns (total 8 columns):
payment_method_id int16
payment_plan_days int16
plan_list_price int16
actual_amount_paid int16
is_auto_renew bool
transaction_date datetime64[ns]
membership_expire_date datetime64[ns]
is_cancel bool
dtypes: bool(2), datetime64[ns](2), int16(4)
memory usage: 698.7+ MB
现在,用dask进行一些简单的计算,我得到以下时序
使用线程
>>>time.asctime();ddf.actual_amount_paid.mean().compute();time.asctime()
'Fri Oct 13 23:44:50 2017'
141.98732048354384
'Fri Oct 13 23:44:59 2017'
使用分布式(本地集群)
>>> c=Client()
>>> time.asctime();ddf.actual_amount_paid.mean().compute();time.asctime()
'Fri Oct 13 23:47:04 2017'
141.98732048354384
'Fri Oct 13 23:47:15 2017'
>>>
没关系,每个大约9秒钟。
现在使用多处理,这就是惊喜……
>>> time.asctime();ddf.actual_amount_paid.mean().compute(get=dask.multiprocessing.get);time.asctime()
'Fri Oct 13 23:50:43 2017'
141.98732048354384
'Fri Oct 13 23:57:49 2017'
>>>
我希望多处理和分布式/本地群集处于相同的数量级,并且在线程方面可能存在一些差异(无论好坏)
但是,在一个in16列中进行简单均值计算需要花费47倍的时间才能完成?
我的环境只是带有所需模块的最新conda安装。没有任何东西。
为什么会有这种差异?我无法管理dask / distributed具有可预测的行为,从而无法根据我的问题的性质在不同的调度程序之间做出明智的选择。
这只是一个玩具示例,但是我一直无法得到一个符合我期望的示例(因为我对阅读文档的了解最少)。
有什么我应该记住的东西吗?还是我完全忘记了要点?
谢谢
杰西
最佳答案
使用线程调度程序,每个任务都可以访问进程的所有内存(在这种情况下为所有数据),因此可以执行其计算而无需复制任何内存。
使用分布式调度程序,调度程序可以知道哪个线程和哪个工作程序正在生成后续任务所需的数据,或者已经在内存中存储了该数据。调度程序的智能性专门用于将计算移至合适的工作人员,以避免数据通信和复制。
相反,多进程调度程序倾向于向主进程发送任务结果或从主进程发送任务结果,这可能涉及大量的序列化和复制。某些任务可以融合在一起(通过在链中调用许多python函数来组合任务),但有些则不能。任何序列化和复制都需要CPU的努力,并且可能对您来说更重要的是存储空间。如果原始数据占系统总数的很大一部分,则可能是物理内存已满,从而导致很大的速度降低。
关于python - 分布式分布式快速镶木中的处理时间不一致,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46738708/