繁体   English   中英

Dask 和 Numba - 如何有效地使用地图分区?

[英]Dask and Numba - How to use map partitions efficiently?

我正在尝试加速我的代码并提高我对 Dask 和 Numba 的理解,我确实尝试在我创建的一些示例中同时使用它们,但没有改进,我不明白为什么。

我必须说,我使用的是四核笔记本电脑,因此改进可能不大,但仍然应该在那里。

更准确地说,在 Windows 10 笔记本电脑上,使用 Python 3.7 并在 conda 环境中使用 Numba 和 Dask。

这是我的代码:

import numpy as np
import pandas as pd
from numba import jit
import dask.dataframe as dd

data = np.random.randint(-10, 10, (10**8, 3))
df = pd.DataFrame(data=data, columns=["A", "B", "C"], index=None)
df["F"] = np.random.choice(["apple", "banana", "orange", 
                            "pear","grape","lime","citrus","peach"],10**8)

正如您所看到的,这是一个非常大的数据帧内存,这是我检查 Dask 是否代表改进的方法。 在较小的数据帧(< 200MB)上,它似乎根本没有区别。

ddf = dd.from_pandas(df,npartitions=12)

@jit
def remove_special_char_with_numba(x):
    return x.replace('r','')

这是一个玩具示例,我尝试从特定列中删除字符串,与普通 Pandas 相比,Numba 确实加快了代码速度,但不支持字符串,因此我无法修改替换或使用 nopython 模式。 现在 :

%%timeit
remove_special_char_with_numba(df["F"])

输出 :

每个循环 58.9 s ± 9.51 s(7 次运行的平均值 ± 标准偏差,每次 1 次循环)

接下来,我对以下内容的理解是 Dask 将我的数据帧分成不同的块/分区,并且它将独立地在每个分离的块上应用该函数。 有四个内核,据我所知,它应该可以加快进程。

%%timeit
ddf["F"].map_partitions(remove_special_char_with_numba).compute()

输出 :

每个循环 45.9 s ± 10.5 s(7 次运行的平均值 ± 标准偏差,每次 1 次循环)

现在我不想贪婪,但改进不应该比这更大吗? 难道我做错了什么 ?

谢谢

这个结果不应该让你感到惊讶。 显然,您在默认线程调度程序上运行。

这意味着每个字符串操作都必须获得单个 python GIL 才能发生,无论它是否在 dask 控制的工作线程中都是如此。 对于 numba-jit 版本的操作仍然如此,因为您无法在 no-python 模式下运行此函数。 如果在无蟒蛇模式,它会释放GIL,以及完整的字符串支持将来到numba。

您可能能够使用具有多个进程的分布式调度程序获得更好的加速,尽管那样您会承受在进程之间发送数据的成本,因此如何生成数据以及您带来所有结果的事实很重要当您compute()时进入主会话。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM