优化

MicroPython 使用了若干优化来节省 RAM,同时也确保程序的高效执行。本章讨论其中的一些优化。

备注

MicroPython 字符串驻留映射与字典 详细介绍了针对字符串和字典的其他优化。

冻结字节码

当 MicroPython 从文件系统加载 Python 代码时,它首先必须将文件解析为临时的内存表示,然后生成用于执行的字节码,两者都存储在堆(RAM)中。这可能会导致占用大量内存。可以使用 MicroPython 交叉编译器生成一个 .mpy 文件,其中包含某个 Python 模块的预编译字节码。该文件仍会被加载到 RAM 中,但它避免了解析阶段的额外开销。

作为进一步的优化,.mpy 文件中的预编译字节码可以在主固件编译过程中被“冻结”进固件镜像,这意味着字节码将从 ROM 中执行。这可以带来显著的内存节省,并减少堆碎片。

更多信息请参阅 MicroPython 清单(manifest)文件

变量

MicroPython 对局部变量和全局变量的处理方式不同。全局变量存储在一个分配于堆上的全局字典中,并从该字典中查找(请注意,每个模块都有自己独立的字典,因此命名空间也是独立的)。另一方面,局部变量存储在 Python 值栈上,该栈可能位于 C 栈或堆上。它们通过其在 Python 栈中的偏移量被直接访问,这比在字典中进行全局查找更高效。

全局变量名的长度也会影响 RAM 的使用量,因为标识符存储在 RAM 中。标识符越短,占用的内存越少。

另一方面,以下划线开头的 const 变量会被视为真正的常量,不会被分配或添加到字典中,从而节省一些内存。这些变量使用 MicroPython 库中的 const()。因此:

from micropython import const

X = const(1)
_Y = const(2)
foo(X, _Y)

编译为:

X = 1
foo(1, 2)

内存分配

大多数常见的 MicroPython 构造不会在堆上分配。但以下情况会:

  • 动态数据结构,如列表、映射等;

  • 函数、类和对象实例;

  • 导入;以及

  • 全局变量的首次赋值(用于在全局字典中创建槽位)。

关于从更以用户为中心的角度对优化进行的详细讨论,请参阅 Maximising MicroPython speed