Optimizações

O MicroPython utiliza várias optimizações para poupar RAM, mas também para garantir a execução eficiente dos programas. Este capítulo discute algumas dessas optimizações.

Nota

Interning de strings no MicroPython e Mapas e Dicionários detalham outras optimizações em cadeias de caracteres e dicionários.

Bytecode congelado

Quando o MicroPython carrega código Python a partir do sistema de ficheiros, tem primeiro de analisar o ficheiro numa representação temporária em memória e depois gerar bytecode para execução, ambos os quais são armazenados no heap (em RAM). Isto pode levar a uma utilização significativa de memória. O compilador cruzado do MicroPython pode ser utilizado para gerar um ficheiro .mpy, contendo o bytecode pré-compilado de um módulo Python. Este ainda será carregado para RAM, mas evita a sobrecarga adicional da fase de análise.

Como optimização adicional, o bytecode pré-compilado de um ficheiro .mpy pode ser «congelado» na imagem do firmware como parte do processo principal de compilação do firmware, o que significa que o bytecode será executado a partir da ROM. Isto pode resultar em poupanças significativas de memória e reduzir a fragmentação do heap.

Consulte Ficheiros de manifesto MicroPython para mais informações.

Variáveis

O MicroPython processa variáveis locais e globais de forma diferente. As variáveis globais são armazenadas e consultadas a partir de um dicionário global que é alocado no heap (note que cada módulo tem o seu próprio dicionário separado, ou seja, namespace separado). As variáveis locais, por outro lado, são armazenadas na pilha de valores Python, que pode residir na pilha C ou no heap. São acedidas directamente pelo seu deslocamento dentro da pilha Python, o que é mais eficiente do que uma pesquisa global num dicionário.

O comprimento dos nomes de variáveis globais também afecta a quantidade de RAM utilizada, uma vez que os identificadores são armazenados em RAM. Quanto mais curto for o identificador, menos memória é utilizada.

O outro aspecto é que as variáveis const que começam com um sublinhado são tratadas como constantes adequadas e não são alocadas nem adicionadas a um dicionário, poupando assim alguma memória. Estas variáveis utilizam const() da biblioteca do MicroPython. Portanto:

from micropython import const

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

Compila para:

X = 1
foo(1, 2)

Alocação de memória

A maioria das construções comuns do MicroPython não são alocadas no heap. No entanto, as seguintes são:

  • Estruturas de dados dinâmicas como listas, mapeamentos, etc.;

  • Funções, classes e instâncias de objectos;

  • importações; e

  • Primeira atribuição de variáveis globais (para criar o slot no dicionário global).

Para uma discussão detalhada numa perspectiva mais centrada no utilizador sobre optimização, consulte Maximising MicroPython speed.