Оптимизации¶
MicroPython использует несколько оптимизаций для экономии ОЗУ, а также для обеспечения эффективного выполнения программ. В этой главе рассматриваются некоторые из этих оптимизаций.
Примечание
Интернирование строк в MicroPython и Отображения и словари подробно описывают другие оптимизации строк и словарей.
Замороженный байт-код¶
Когда MicroPython загружает код Python из файловой системы, ему сначала необходимо разобрать файл во временное представление в памяти, а затем сгенерировать байт-код для выполнения, и то и другое хранится в куче (в ОЗУ). Это может приводить к использованию значительных объёмов памяти. Кросс-компилятор MicroPython можно использовать для генерации файла .mpy, содержащего предварительно скомпилированный байт-код для модуля Python. Он по-прежнему будет загружаться в ОЗУ, но это позволяет избежать дополнительных накладных расходов на этап разбора.
В качестве дальнейшей оптимизации предварительно скомпилированный байт-код из файла .mpy может быть «заморожен» в образе прошивки как часть процесса компиляции основной прошивки, что означает, что байт-код будет выполняться из ПЗУ. Это может привести к значительной экономии памяти и уменьшить фрагментацию кучи.
Дополнительную информацию см. в Файлы манифеста MicroPython.
Переменные¶
MicroPython обрабатывает локальные и глобальные переменные по-разному. Глобальные переменные хранятся в глобальном словаре, выделенном в куче, и ищутся в нём (обратите внимание, что у каждого модуля есть свой отдельный словарь, а значит, и отдельное пространство имён). Локальные же переменные хранятся в стеке значений Python, который может располагаться в стеке C или в куче. Доступ к ним осуществляется напрямую по их смещению в стеке Python, что более эффективно, чем глобальный поиск в словаре.
Длина имён глобальных переменных также влияет на то, сколько ОЗУ используется, так как идентификаторы хранятся в ОЗУ. Чем короче идентификатор, тем меньше памяти используется.
Другой аспект заключается в том, что переменные const, начинающиеся с подчёркивания, рассматриваются как настоящие константы и не выделяются и не добавляются в словарь, что позволяет сэкономить некоторое количество памяти. Эти переменные используют const() из библиотеки MicroPython. Таким образом:
from micropython import const
X = const(1)
_Y = const(2)
foo(X, _Y)
Компилируется в:
X = 1
foo(1, 2)
Выделение памяти¶
Большинство распространённых конструкций MicroPython не выделяются в куче. Однако следующие выделяются:
динамические структуры данных, такие как списки, отображения и т. д.;
функции, классы и экземпляры объектов;
импорты; и
первое присваивание глобальных переменных (для создания слота в глобальном словаре).
Подробное обсуждение оптимизации с более ориентированной на пользователя точки зрения см. в Максимизация скорости MicroPython.