优化¶
MicroPython 使用多项优化来实现,在节省 RAM 的前提下保证了程序的有效执行。本章节将介绍这些优化。
备注
MicroPython 字符串驻留 和 映射(Maps)与字典(Dictionaries) 详细介绍了字符串和字典上的其他优化。
冻结字节码¶
当 MicroPython 从文件系统加载 Python 代码时,它首先必须将文件解析为在内存中的临时表示形式,再生成可执行的字节码,这两者都存储在(在 RAM 中)的堆上。这可能导致大量的内存占用。要解决这一问题, 可使用 MicroPython 交叉编译器生成一个 .mpy
文件,其中包含了一个 Python 模块的预编译字节码,虽然该文件仍会被加载到 RAM 中,但这种方式避免了解析阶段的额外开销。
作为进一步的优化,一个 .mpy
文件中的预编译字节码可以在主固件编译阶段冻结到固件中,这意味着字节码将从 ROM 中执行。这可以显著节省内存,并减少堆碎片。
变量¶
在 MicroPython 中,处理局部变量和全局变量的方式是不同的。全局变量从在堆上分配的全局字典中存储和检索(请注意,每个模块都有自己单独的字典,因此需要独立的命名空间)。局部变量则存储在 Python 值栈中,可能存储在 C 的栈或堆中。它们通过在 Python 栈中的偏移量直接访问,这比在字典中全局查找更有效。
全局变量名称的长度也会影响存储标识符时所占用的内存。标识符越短,则所占用的内存越少。
另一方面,以下划线开头的 const
变量被视为妥善的常量,不会被分配或添加到字典中,因此节省了一部分内存。这些变量需要以 MicroPython 库中的 const()
函数创建。因此:
from micropython import const
X = const(1)
_Y = const(2)
foo(X, _Y)
编译为:
X = 1
foo(1, 2)
内存分配¶
大多数的 MicroPython 的构造都不会分配在堆上。但是以下构造器则会:
动态数据结构,如列表,映射等;
函数,类和对象实例;
使用 import 导入的模块;
全局变量的首次赋值(通过在全局字典中创建槽)。
有关更以用户为中心的优化视角的详细讨论,参阅 最大化 MicroPython 速度 。