Numba:何时使用 nopython=True?

cha*_*l-f 1 python time jit numba

我有以下设置:

\n
import numpy as np\nimport matplotlib.pyplot as plt\nimport timeit\nimport numba\n
Run Code Online (Sandbox Code Playgroud)\n
@numba.jit(nopython=True, cache=True)\ndef f(x):\n    summ = 0\n    for i in x:\n        summ += i\n    return summ\n\n@numba.jit(nopython=True)\ndef g21(N, locs):\n    rvs = np.random.normal(loc=locs, scale=locs, size=N)\n    res = f(rvs)\n    return res\n\n@numba.jit(nopython=False)\ndef g22(N, locs):\n    rvs = np.random.normal(loc=locs, scale=locs, size=N)\n    res = f(rvs)\n    return res\n
Run Code Online (Sandbox Code Playgroud)\n

g22g21是完全相同的功能,只是其中一个具有nopython=True而另一个具有nopython=False

\n

现在我给他们一个意见。如果locs是标量,那么 numba 应该能够编译所有内容,因为它们支持numpy.random.normal()此签名。但是,如果locs是一个数组,则 numba 不支持此签名,应返回到 python 解释器。

\n

我首先运行它只是为了编译函数

\n
N = 10_000\n\ng22(N, 3)\ng22(N, np.linspace(0,1,N))\ng21(N, 3)\n# g21(N, np.linspace(0,1,N))  # returns an error\n
Run Code Online (Sandbox Code Playgroud)\n

现在我进行速度比较

\n
N = 10_000\n\ng22(N, 3)\ng22(N, np.linspace(0,1,N))\ng21(N, 3)\n# g21(N, np.linspace(0,1,N))  # returns an error\n
Run Code Online (Sandbox Code Playgroud)\n

返回

\n
274 \xc2\xb5s \xc2\xb1 3.43 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 1,000 loops each)\n270 \xc2\xb5s \xc2\xb1 5.38 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 1,000 loops each)\n421 \xc2\xb5s \xc2\xb1 54.3 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 1,000 loops each)\n
Run Code Online (Sandbox Code Playgroud)\n

g22(N, np.linspace(0,1,N)这是最慢的,因为它返回到 python 解释器,这是有道理的。

\n

然而我不明白的是,尽管一个有,另一个没有,但它的g21(N, 3)速度大致相同。g22(N, 3)nopython=True

\n

g22(N,3)它有一个很大的优点,那就是它可以采用另一个参数,即g22(N, np.linspace(0,1,N)),因此它更通用,但同时没有速度损失nopython=False

\n

所以我的问题是:

\n
    \n
  1. nopython=True在这种情况下,如果 的函数达到相同的速度,那么using 有什么用呢nopython=False

    \n
  2. \n
  3. 在哪种具体情况nopython=True下比 更好nopython=False

    \n
  4. \n
\n

Jér*_*ard 5

  1. 在这种情况下,如果 nopython=False 的函数达到相同的速度,那么使用 nopython=True 有什么用呢?
  2. 在哪种具体情况下 nopython=True 比 nopython=False 更好?

文档指出

Numba 有两种编译模式:nopython 模式和 object 模式。前者生成的代码要快得多,但其局限性可能迫使 Numba 回退到后者。为了防止 Numba 回退并引发错误,请传递nopython=True

请注意,Numba 会尝试在两种模式下将代码编译为本机二进制文件。然而,nopython当这不可能时,会产生错误,而另一个会产生警告并导致使用回退代码。

对于某些应用程序,性能可能至关重要,因此您确实不希望调用回退代码。例如,高性能应用程序就是这种情况。在这种情况下出现错误比在昂贵的机器(如超级计算机或计算服务器)上运行几天而不是几分钟的代码要好。由于功能不受支持,使用不同版本的 Numba 可能会在某些计算机上默默地导致回退。我个人总是使用该nopython模式来防止这种情况(因为回退代码通常太慢而无用),并且我认为对象模式有点无用。看跌期权短期内nopython为业绩提供了更有力的保证