Python 使用numba.jit编译条件数组需要很长时间

Python 使用numba.jit编译条件数组需要很长时间,python,time,conditional-statements,jit,numba,Python,Time,Conditional Statements,Jit,Numba,如果我试图用numba的jit编译器编译一个包含一系列条件的函数,它需要很长时间。这个程序看起来基本上像 from numba import jit import numpy as np @jit(nopython=True) def foo(a, b): valid = [ (a - 1 >= 0) and (b - 1 >= 0), (a - 1 >= 0) and (b - 1 >= 0), (a - 1 &

如果我试图用numba的jit编译器编译一个包含一系列条件的函数,它需要很长时间。这个程序看起来基本上像

from numba import jit
import numpy as np

@jit(nopython=True)
def foo(a, b):
    valid = [
        (a - 1 >= 0) and (b - 1 >= 0),
        (a - 1 >= 0) and (b - 1 >= 0),
        (a - 1 >= 0) and (b - 1 >= 0),
        (a - 1 >= 0) and (b - 1 >= 0),
        (a - 1 >= 0) and (b - 1 >= 0),
        (a - 1 >= 0) and (b - 1 >= 0),
        (a - 1 >= 0) and (b - 1 >= 0),
        (a - 1 >= 0) and (b - 1 >= 0),
        (a - 1 >= 0) and (b - 1 >= 0),
        (a - 1 >= 0) and (b - 1 >= 0),
        (a - 1 >= 0) and (b - 1 >= 0),
        (a - 1 >= 0) and (b - 1 >= 0),
        (a - 1 >= 0) and (b - 1 >= 0),
        (a - 1 >= 0) and (b - 1 >= 0),
        (a - 1 >= 0) and (b - 1 >= 0),
        (a - 1 >= 0) and (b - 1 >= 0),
        (a - 1 >= 0) and (b - 1 >= 0),
        (a - 1 >= 0) and (b - 1 >= 0),
        (a - 1 >= 0) and (b - 1 >= 0),
        (a - 1 >= 0) and (b - 1 >= 0),
        (a - 1 >= 0) and (b - 1 >= 0),
        (a - 1 >= 0) and (b - 1 >= 0),
        (a - 1 >= 0) and (b - 1 >= 0)
    ]

foo(1, 1)
我排除了不会显著改变编译时间的所有内容。如果我使用超过20个元素,问题就会出现

| elements | time |
-------------------
|    21    | 2.7s |
|    22    | 5.1s |
|    23    |  10s |
|   ...    |  ... |
-------------------
尽管如此,该功能运行良好。有人知道,为什么用numba编译这样的函数需要这么长时间吗?以类似的方式使用整数或浮点数组合创建数组不会产生任何问题

  • 您可能希望在numba上报告这一点,因为它的伸缩性很差,感觉编译器中出现了一些错误

  • <>你也可以考虑如果你真的需要大量这样的数组语句,如果问题可以更清楚地重构。例如,
    valid
    是否可以根据需要调用函数,而不是布尔数组

  • 综上所述,当前版本的numba中的一个解决方案是展开条件

  • 例如:

    # "codegen"
    for i in range(23):
        print(f'    valid[{i}] = (a - 1 >= 0) and (b - 1 >= 0)')
    
    @jit(nopython=True)
    def foo(a, b):
        valid = np.empty(23, dtype=np.bool_)
        valid[0] = (a - 1 >= 0) and (b - 1 >= 0)
        valid[1] = (a - 1 >= 0) and (b - 1 >= 0)
        valid[2] = (a - 1 >= 0) and (b - 1 >= 0)
        valid[3] = (a - 1 >= 0) and (b - 1 >= 0)
        valid[4] = (a - 1 >= 0) and (b - 1 >= 0)
        valid[5] = (a - 1 >= 0) and (b - 1 >= 0)
        valid[6] = (a - 1 >= 0) and (b - 1 >= 0)
        valid[7] = (a - 1 >= 0) and (b - 1 >= 0)
        valid[8] = (a - 1 >= 0) and (b - 1 >= 0)
        valid[9] = (a - 1 >= 0) and (b - 1 >= 0)
        valid[10] = (a - 1 >= 0) and (b - 1 >= 0)
        valid[11] = (a - 1 >= 0) and (b - 1 >= 0)
        valid[12] = (a - 1 >= 0) and (b - 1 >= 0)
        valid[13] = (a - 1 >= 0) and (b - 1 >= 0)
        valid[14] = (a - 1 >= 0) and (b - 1 >= 0)
        valid[15] = (a - 1 >= 0) and (b - 1 >= 0)
        valid[16] = (a - 1 >= 0) and (b - 1 >= 0)
        valid[17] = (a - 1 >= 0) and (b - 1 >= 0)
        valid[18] = (a - 1 >= 0) and (b - 1 >= 0)
        valid[19] = (a - 1 >= 0) and (b - 1 >= 0)
        valid[20] = (a - 1 >= 0) and (b - 1 >= 0)
        valid[21] = (a - 1 >= 0) and (b - 1 >= 0)
        valid[22] = (a - 1 >= 0) and (b - 1 >= 0)
    
    %time foo(1,1)
    Wall time: 274 ms
    

    你能提供一个可运行的完整示例吗?@JoshAdel我更改了示例,它现在可运行且更简单。在我原来的函数中,所有条件都不同,我必须使用
    有效的
    索引多个其他数组。使用数组而不是if语句似乎是更快、更可读的选择。我提出了一个问题,如果有什么变化,我会更新我的问题。