Skip to content

docs: Document @micropython.native usage policy. #405

@nedseb

Description

@nedseb

Context

Several recent example PRs (#390, #391) use @micropython.native on functions to get faster execution. The decorator compiles a function to native ARM code instead of MicroPython bytecode, which can yield 2-10x speedups on CPU-bound loops. However, it is not always beneficial and has constraints that should be documented.

Guidelines to adopt

Where @micropython.native is useful

Example files with pixel-level rendering loops, where the CPU is the bottleneck:

  • draw_character() (tamagotchi) — 4 nested loops, pixel by pixel
  • fill_circle() (spirit_level) — double loop with x²+y² test
  • draw_maze() (maze_game) — double loop over the grid
  • Any tight numerical loop that does not call I/O

Where @micropython.native is NOT useful

  • Driver code (device.py) — methods are dominated by I2C/SPI bus time (100-400 kHz). Compiling _read_reg() to native code saves microseconds on a millisecond-scale operation. The added complexity (larger binary, reduced debuggability) is not worth it.
  • Functions with few operations — e.g. compute_display() in radar_screen.py does 3 comparisons; native compilation gains nothing measurable.
  • Functions using unsupported features — generators, closures, with statements, and some exception patterns are not supported by the native emitter and will cause a compile-time error.

Constraints

  • Only works on ARM targets (not a problem for STeaMi, always STM32)
  • Native code uses more RAM per function than bytecode
  • Errors in native functions produce less helpful tracebacks
  • Not portable to CPython (requires a try: import micropython guard or per-file ignore in tests/stubs)

Proposed policy

  1. Drivers: do not use @micropython.native. Keep driver code portable and debuggable.
  2. Examples: accept on a case-by-case basis for rendering hot-paths where the speedup is measurable and the function is compatible with native compilation.
  3. Do not enforce via linting — this is a judgment call, not a mechanical rule.
  4. Document this policy in CONTRIBUTING.md under "Coding conventions".

Tasks

  • Add a short guideline to CONTRIBUTING.md (coding conventions section)
  • Review existing uses: remove @micropython.native from compute_display() in radar_screen.py (no measurable benefit on 3 comparisons)

Metadata

Metadata

Assignees

Labels

documentationImprovements or additions to documentation

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions