Оптимизации

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.