numba 如何推断字面上初始化的局部变量的类型?

How does numba infer the types of literally initialized locals?

Numba 做了一些很酷和令人惊讶的事情:

@jit(nopython=True, nogil=True)
def sum(arr):
    result = 0
    for i in range(len(arr)):
        result += arr[i]
    return result

当使用 int64 数组调用时,它 returns 是一个 int。当使用 float64 调用时,它 returns 一个浮点数。

这是令人惊讶的,因为结果是用文字整数 0 初始化的——我认为它将确定结果的类型。为什么结果不总是一个整数?

这是 sum.inspecttypes() 对 float64 数组情况的说明:

================================================================================
sum (readonly array(float64, 1d, C),)
--------------------------------------------------------------------------------
# File: /home/.../fast_ops.py
# --- LINE 164 --- 
# label 0
#   del $const0.1

@jit(nopython=True, nogil=True)

# --- LINE 165 --- 

def sum(arr):

    # --- LINE 166 --- 
    #   arr = arg(0, name=arr)  :: readonly array(float64, 1d, C)
    #   $const0.1 = const(int, 0)  :: int64
    #   result = $const0.1  :: float64
    #   jump 6
    # label 6

    result = 0

有关高级说明 - 请参阅文档 here。这是基于我(有限的!)理解的复述。

在 numba 的编译过程中,有一个类型统一 process/solver 可以将所有内容转换为高效的低级操作。这可以根据输入生成函数的多个版本。

在你的函数中,一个约束是这一行 - resultarr[i] 必须 是同一类型。

result += arr[i]

如果没有输入,result 将是一个整数。但是在 arr 是双精度的情况下,统一类型的唯一无损方法是将 result 转换为双精度。如果你走另一条路,将 arr 转换为 int,你会破坏信息。