Otimizações¶
O MicroPython usa várias otimizações para economizar RAM, mas também para garantir a execução eficiente dos programas. Este capítulo discute algumas dessas otimizações.
Nota
Internamento de strings no MicroPython e Mapas e Dicionários detalham outras otimizações em strings e dicionários.
Bytecode congelado¶
Quando o MicroPython carrega código Python do sistema de arquivos, ele primeiro precisa analisar o arquivo em uma representação temporária em memória e então gerar o bytecode para execução, sendo que ambos são armazenados no heap (na RAM). Isso pode levar ao uso de quantidades significativas de memória. O compilador cruzado do MicroPython pode ser usado para gerar um arquivo .mpy, contendo o bytecode pré-compilado de um módulo Python. Esse arquivo ainda será carregado na RAM, mas evita a sobrecarga adicional do estágio de análise.
Como otimização adicional, o bytecode pré-compilado de um arquivo .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. Isso pode levar a uma economia significativa de memória e reduzir a fragmentação do heap.
Veja Arquivos de manifesto do MicroPython para mais informações.
Variáveis¶
O MicroPython processa variáveis locais e globais de maneiras diferentes. As variáveis globais são armazenadas e consultadas a partir de um dicionário global que é alocado no heap (observe que cada módulo tem seu próprio dicionário separado, portanto um namespace separado). As variáveis locais, por outro lado, são armazenadas na pilha de valores do Python, que pode residir na pilha C ou no heap. Elas são acessadas diretamente por seu deslocamento dentro da pilha do Python, o que é mais eficiente do que uma consulta global em um dicionário.
O comprimento dos nomes das variáveis globais também afeta a quantidade de RAM utilizada, pois os identificadores são armazenados na RAM. Quanto mais curto o identificador, menos memória é usada.
O outro aspecto é que variáveis const que começam com um sublinhado são tratadas como constantes propriamente ditas e não são alocadas nem adicionadas a um dicionário, economizando assim alguma memória. Essas variáveis usam 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 é alocada no heap. No entanto, as seguintes são:
Estruturas de dados dinâmicas como listas, mapeamentos, etc;
Funções, classes e instâncias de objetos;
imports; e
Primeira atribuição de variáveis globais (para criar o slot no dicionário global).
Para uma discussão detalhada sob uma perspectiva mais centrada no usuário sobre otimização, veja Maximizando a velocidade do MicroPython.