Back to main page

Week 3 Group Assignment

Comparing C++ to MicroPython and Rust

Programming speeds and memory handling vary greatly depending on the language used. This is because going from binary code to a human-understandable language requires abstractions and simplicity that trade off optimality for simplicity and versatility. While C++ is known for its speed as a "low-level" programming language (despite being much higher-level when compared to other languages like Assembly), it's also notorious for its complicated memory allocation system, opening the door to memory errors that can crash the program or create critical vulnerabilities.

Here, we therefore compare C++ to two alternatives: MicroPython, a language designed to be easy to understand while trading off performance, and Rust, a more complicated language that maintains C++ performance while ensuring memory safety. One thing to note with MicroPython is that some tricks can be used to keep the simplicity while using C under the hood as much as possible. Running some benchmarks, we can quantify all of those differences in performance across languages with exactitude.

Measure (on the QPAD)C++RustMicroPython optimizedMicroPython naive
Program size106.6 KB61.8 KB46.0 KB + 338.7 KB firmware59.2 KB + 338.7 KB firmware
RAM16.6 KB1.3 KB106.8 KB54.6 KB
Frame rate30.3 fps30.3 fps25.4 fps2.6 fps
Frame time (average)31.4 ms27.2 ms39.4 ms381.1 ms
Drawing the frame2.1 ms0.8 ms11.9 ms336.1 ms
Sending the frame to the screen27.8 ms25.2 ms26.0 ms26.0 ms
Reading the six pads1.5 ms1.3 ms1.2 ms18.6 ms
Game speed vs real time100%100%84%8.7%
Evaluating a 7-card poker hand0.21 ms0.18 ms1.42 ms42.0 ms
Memory allocated per frame0 B0 B (no heap)2 B10.4 KB
Whole benchmark run66 s54 s2.6 min42.5 min
Measure for Alexandre Bismuth's casino game - Full benchmark and code

What we observe on a high-level is that while Rust and C++ are competitive for this game, using MicroPython is orders of magnitude off the pace. Using optimizations to rely on C under the hood makes our program close to competitive but still not at the same level as Rust and C++.
One conclusion can be that, since coding agents shift the focus from simplicity to safety and performance, an attractive option is to use Rust, obtaining the C++ performance gains (or better) while having the memory allocation safety of a higher-level language.

Choosing your IDE

A short comment can also be made about developing in different IDEs. To program an embedded device in C++, the simplest and often best option is to use the Arduino IDE. From a user perspective, this environment is very beginner-friendly. It is quite intuitive to use and requires very little setup. On the other hand, most of the other IDEs such as Visual Studio Code require a more complicated setup that is harder to manipulate for beginners and often time-consuming regardless of experience. Even if this can be mitigated with the help of AI agents that automate the setup process, we still believe that the Arduino IDE is the best choice for C++ programs.

To use Rust or MicroPython, the Arduino IDE is not an option. Therefore, one alternative is to use the more flexible Visual Studio Code. Here, with the guidance of an LLM, we follow a few setup steps (executing the commands ourselves to ensure understanding). Once that is done, using VS Code is similar in difficulty to the Arduino IDE, with the difference that we must use terminal commands instead of click-and-play buttons.

All in all, the takeaway here can be summarized as "Use the Arduino IDE if you program in C++, and VS Code otherwise!".