为什么numba不优化代码中调用的子程序?

时间:2015-04-13 20:55:28

标签: python optimization jit numba

我是numba的新手,并尝试使用@jit来加速Python程序,但这只会影响我的代码。当我的代码调用另一个子例程时,似乎这个子例程在执行之前没有得到优化。

当然我可以@jit修饰所有函数,但是当涉及到我只消耗的函数(没有自己开发)时,这是有限的。

请参阅以下基于π的Leibniz公式的示例。

def leibniz1(n):
    operand = 1.0
    result = 0.0
    for i in xrange(1, n*2, 2):
        result += operand / i
        operand = - operand
    return result * 4

leibniz1的运行时间(10000000):约。 0.8秒

当我添加

from numba import jit, int32

并使用@jit

修饰函数
@jit
def leibniz2(n):
    operand = 1.0
    result = 0.0
    for i in xrange(1, n*2, 2):
        result += operand / i
        operand = - operand
    return result * 4

10000000次迭代的运行时间减少到大约。 0.1秒。

问题出现在这里:

@jit
def leibniz3(n):
     return leibniz1(n)

我希望leibniz3得到优化,leibniz1也是如此 - 因为它是从优化函数中调用的。但情况并非如此,运行时间再次约为。 0.8秒,这是纯粹的leibniz1值。

有没有机会用numba或类似的东西实现我的计划,因为我不能@jit装饰我的程序所依赖的所有功能,因为它们不是来自我。

1 个答案:

答案 0 :(得分:1)

首先,我建议使用nopython参数:

@jit(nopython=True)
def f(x):
    ....

这样就可以强制C / Fortran编译函数,如果失败则会出现显式错误。 来自Documentation

  

Numba有两种编译模式:nopython模式和对象模式。前者产生更快的代码,但有一些限制可以迫使Numba回到后者。为防止Numba退回,而是引发错误,请传递nopython = True。

同样在文件中说明:

  

必须将@jit装饰器添加到任何此类库函数中,否则Numba可能会生成更慢的代码。

基本上你的问题就像你想在纯C / Fortran中用高级语言调用一个函数一样。 所以不幸的是,据我所知,没有其他解决办法,只能重新实现你的贴近机器代码中的其他功能。