Python 为什么';t numba优化代码中调用的子例程?

Python 为什么';t numba优化代码中调用的子例程?,python,optimization,jit,numba,Python,Optimization,Jit,Numba,我是numba新手,尝试使用@jit来加速Python程序,但这只会影响我的代码。当我的代码调用另一个子例程时,似乎这一个子例程在执行之前没有得到优化 当然,我可以@jit修饰所有函数,但当涉及到我只使用的函数时(没有自己开发它们),这是有限的 请参见以下基于π的莱布尼兹公式的示例 def leibniz1(n): operand = 1.0 result = 0.0 for i in xrange(1, n*2, 2): result += operan

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

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

请参见以下基于π的莱布尼兹公式的示例

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
莱布尼兹1的运行时间(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秒,这是纯莱布尼兹值


是否有机会使用numba或类似工具实现我的计划,因为我无法@jit修饰我的程序所依赖的所有函数,因为它们不是我的。

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

@jit(nopython=True)
def f(x):
    ....
通过这种方式,您可以强制执行类似于C/Fortran的函数编译,如果编译失败,您将得到一个显式错误。 从:

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

文件中还规定:

必须将@jit decorator添加到任何此类库函数中,否则Numba可能会生成慢得多的代码

基本上,您的问题与从纯C/Fortran高级语言调用函数的问题相同。 不幸的是,据我所知,除了重新实现机器代码中的其他函数外,没有其他解决方案。

首先-Numba只支持(以一种加速的方式)相当有限的Python范围,因此如果您无法访问这些函数,您可能会发现无法使其工作得太好。第二,您可以始终对您没有编写的jit函数执行
jitted\u function=numba.jit()(some\u other\u module.function)
[-记住,装饰器只是一个函数调用!]。