术语表

提前编译
AOT 编译
AOT

在程序代码运行之前,在一个单独的步骤中编译函数,生成一个可以独立分发的磁盘二进制对象。这是 C、C++ 或 Fortran 等语言中已知的传统编译方式。

字节码
Python 字节码

Python 函数执行的原始形式。Python 字节码描述了一个堆栈机器,它使用函数堆栈和执行环境(例如全局变量)中的操作数执行抽象(无类型)操作。

编译时常量

Numba 可以在编译时推断和冻结其值的表达式。全局变量和闭包变量是编译时常量。

即时编译
JIT 编译
JIT

在执行时编译函数,与提前编译相对。

JIT 函数

“使用 @jit 装饰器通过 Numba JIT 编译的函数”的简称。

提升循环
循环提升
循环 JIT

对象模式下编译的一项特性,在此模式下,循环可以自动提取并以 nopython 模式编译。这使得在 nopython 模式中不支持某些操作的函数,如果其循环中只包含 nopython 支持的操作,也能看到显著的性能提升。

降级

Numba IR 转换为 LLVM IR 的过程。“降级”一词源于 LLVM IR 是低级且机器特定的,而 Numba IR 是高级且抽象的这一事实。

NPM
nopython 模式

Numba 的一种编译模式,它生成不访问 Python C API 的代码。这种编译模式可生成最高性能的代码,但要求函数中所有值的原生类型都可以被推断

注意

在 Numba 0.59 之前,@jit 默认不设置 nopython=True,并允许自动回退到对象模式

Numba IR
Numba 中间表示

Python 代码片段的一种表示形式,它比原始的 Python 字节码更易于分析和转换。

对象模式

Numba 的一种编译模式,它生成的代码将所有值作为 Python 对象处理,并使用 Python C API 对这些对象执行所有操作。以对象模式编译的代码通常不会比 Python 解释代码运行得更快,除非 Numba 编译器可以利用循环 JIT

OptionalType

一个 OptionalType 实际上是 typeNone 的类型联合。它们通常出现在实践中,因为变量被设置为 None,然后在某个分支中变量被设置为其他值。在编译时通常无法确定分支是否会执行,因此为了允许类型推断完成,变量的类型就变成了 type(来自值)和 None 的联合,即 OptionalType(type)

类型推断

Numba 确定正在编译的函数中所有值的专门类型(specialized types)的过程。如果参数或全局变量具有 Numba 不认识的 Python 类型,或者使用了 Numba 不识别的函数,类型推断可能会失败。成功的类型推断是nopython 模式下编译的先决条件。

类型化

对值或操作执行类型推断的行为。

ufunc

一个 NumPy 通用函数。Numba 可以使用 @vectorize 装饰器创建新的编译后的 ufunc。

反射

在 Numba 中,当一个可变容器从 Python 解释器作为参数传递给一个 nopython 函数时,该容器对象及其所有包含的元素都被转换为 nopython 值。为了匹配 Python 的语义,nopython 函数内部对容器的任何修改都必须在 Python 解释器中可见。为此,Numba 必须在转换回解释器时更新容器及其元素,并将它们转换回 Python 对象。

不要与 Python 在二元运算符上下文中的“反射”混淆(参见 https://docs.pythonlang.cn/3.5/reference/datamodel.html)。