术语表
- 提前编译
- AOT 编译
- AOT
在程序代码运行之前,在一个单独的步骤中编译函数,生成一个可以独立分发的磁盘二进制对象。这是 C、C++ 或 Fortran 等语言中已知的传统编译方式。
- 字节码
- Python 字节码
Python 函数执行的原始形式。Python 字节码描述了一个堆栈机器,它使用函数堆栈和执行环境(例如全局变量)中的操作数执行抽象(无类型)操作。
- 编译时常量
Numba 可以在编译时推断和冻结其值的表达式。全局变量和闭包变量是编译时常量。
- 即时编译
- JIT 编译
- JIT
在执行时编译函数,与提前编译相对。
- 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
实际上是type
和None
的类型联合。它们通常出现在实践中,因为变量被设置为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)。