Optimizaciones¶
MicroPython usa varias optimizaciones para ahorrar RAM pero también para garantizar la ejecución eficiente de los programas. Este capítulo trata algunas de estas optimizaciones.
Nota
Internado de cadenas en MicroPython y Mapas y diccionarios detallan otras optimizaciones sobre cadenas y diccionarios.
Bytecode congelado¶
Cuando MicroPython carga código Python desde el sistema de archivos, primero tiene que analizar el archivo en una representación temporal en memoria, y luego generar bytecode para su ejecución, ambos de los cuales se almacenan en el heap (en RAM). Esto puede llevar a que se use una cantidad significativa de memoria. El compilador cruzado de MicroPython puede usarse para generar un archivo .mpy, que contiene el bytecode precompilado de un módulo Python. Este aún se cargará en RAM, pero evita la sobrecarga adicional de la etapa de análisis.
Como optimización adicional, el bytecode precompilado de un archivo .mpy puede «congelarse» dentro de la imagen del firmware como parte del proceso de compilación del firmware principal, lo que significa que el bytecode se ejecutará desde la ROM. Esto puede llevar a un ahorro significativo de memoria, y reducir la fragmentación del heap.
Véase Archivos de manifiesto de MicroPython para más información.
Variables¶
MicroPython procesa las variables locales y globales de forma diferente. Las variables globales se almacenan y se buscan en un diccionario global que se reserva en el heap (tenga en cuenta que cada módulo tiene su propio dict separado, y por tanto un espacio de nombres separado). Las variables locales, por otro lado, se almacenan en la pila de valores de Python, que puede residir en la pila de C o en el heap. Se accede a ellas directamente por su desplazamiento dentro de la pila de Python, lo cual es más eficiente que una búsqueda global en un dict.
La longitud de los nombres de las variables globales también afecta a la cantidad de RAM que se usa, ya que los identificadores se almacenan en RAM. Cuanto más corto sea el identificador, menos memoria se usa.
El otro aspecto es que las variables const que empiezan por un guion bajo se tratan como constantes propiamente dichas y no se reservan ni se añaden a un diccionario, ahorrando así algo de memoria. Estas variables usan const() de la biblioteca de MicroPython. Por lo tanto:
from micropython import const
X = const(1)
_Y = const(2)
foo(X, _Y)
Se compila a:
X = 1
foo(1, 2)
Asignación de memoria¶
La mayoría de las construcciones comunes de MicroPython no se reservan en el heap. Sin embargo, las siguientes sí lo hacen:
Estructuras de datos dinámicas como listas, mapeos, etc.;
Funciones, clases e instancias de objetos;
importaciones; y
La primera asignación de variables globales (para crear el slot en el dict global).
Para una discusión detallada sobre una perspectiva más centrada en el usuario respecto a la optimización, véase Maximizar la velocidad de MicroPython.