Optimisations

MicroPython utilise plusieurs optimisations pour économiser de la RAM mais aussi pour garantir l’exécution efficace des programmes. Ce chapitre aborde certaines de ces optimisations.

Note

L’internement de chaînes de MicroPython et Maps et dictionnaires détaillent d’autres optimisations sur les chaînes et les dictionnaires.

Bytecode figé

Lorsque MicroPython charge du code Python depuis le système de fichiers, il doit d’abord analyser le fichier pour en produire une représentation temporaire en mémoire, puis générer le bytecode pour l’exécution, les deux étant stockés sur le tas (en RAM). Cela peut conduire à une utilisation importante de la mémoire. Le compilateur croisé MicroPython peut être utilisé pour générer un fichier .mpy, contenant le bytecode précompilé d’un module Python. Celui-ci sera toujours chargé en RAM, mais il évite la surcharge supplémentaire de l’étape d’analyse.

Comme optimisation supplémentaire, le bytecode précompilé d’un fichier .mpy peut être « figé » dans l’image du micrologiciel dans le cadre du processus de compilation du micrologiciel principal, ce qui signifie que le bytecode sera exécuté depuis la ROM. Cela peut conduire à une économie de mémoire significative et réduire la fragmentation du tas.

Voir Fichiers manifest de MicroPython pour plus d’informations.

Variables

MicroPython traite les variables locales et globales différemment. Les variables globales sont stockées et recherchées dans un dictionnaire global alloué sur le tas (notez que chaque module possède son propre dictionnaire distinct, donc un espace de noms distinct). Les variables locales, en revanche, sont stockées sur la pile de valeurs Python, qui peut résider sur la pile C ou sur le tas. Elles sont accessibles directement par leur décalage au sein de la pile Python, ce qui est plus efficace qu’une recherche globale dans un dictionnaire.

La longueur des noms des variables globales influe également sur la quantité de RAM utilisée, car les identifiants sont stockés en RAM. Plus l’identifiant est court, moins de mémoire est utilisée.

L’autre aspect est que les variables const dont le nom commence par un trait de soulignement sont traitées comme de véritables constantes et ne sont ni allouées ni ajoutées dans un dictionnaire, ce qui économise de la mémoire. Ces variables utilisent const() de la bibliothèque MicroPython. Ainsi :

from micropython import const

X = const(1)
_Y = const(2)
foo(X, _Y)

Compile en :

X = 1
foo(1, 2)

Allocation de mémoire

La plupart des constructions courantes de MicroPython ne sont pas allouées sur le tas. Cependant, les suivantes le sont :

  • les structures de données dynamiques comme les listes, les mappages, etc. ;

  • les fonctions, les classes et les instances d’objets ;

  • les importations ; et

  • la première affectation des variables globales (pour créer l’emplacement dans le dictionnaire global).

Pour une discussion détaillée d’un point de vue plus centré sur l’utilisateur concernant l’optimisation, voir Maximiser la vitesse de MicroPython.