优化¶
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。