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 可以将所有内容转换为高效的低级操作。这可以根据输入生成函数的多个版本。
在你的函数中,一个约束是这一行 - result
和 arr[i]
必须 是同一类型。
result += arr[i]
如果没有输入,result
将是一个整数。但是在 arr
是双精度的情况下,统一类型的唯一无损方法是将 result
转换为双精度。如果你走另一条路,将 arr
转换为 int,你会破坏信息。
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 可以将所有内容转换为高效的低级操作。这可以根据输入生成函数的多个版本。
在你的函数中,一个约束是这一行 - result
和 arr[i]
必须 是同一类型。
result += arr[i]
如果没有输入,result
将是一个整数。但是在 arr
是双精度的情况下,统一类型的唯一无损方法是将 result
转换为双精度。如果你走另一条路,将 arr
转换为 int,你会破坏信息。