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++ | Rust | MicroPython optimized | MicroPython naive |
|---|---|---|---|---|
| Program size | 106.6 KB | 61.8 KB | 46.0 KB + 338.7 KB firmware | 59.2 KB + 338.7 KB firmware |
| RAM | 16.6 KB | 1.3 KB | 106.8 KB | 54.6 KB |
| Frame rate | 30.3 fps | 30.3 fps | 25.4 fps | 2.6 fps |
| Frame time (average) | 31.4 ms | 27.2 ms | 39.4 ms | 381.1 ms |
| Drawing the frame | 2.1 ms | 0.8 ms | 11.9 ms | 336.1 ms |
| Sending the frame to the screen | 27.8 ms | 25.2 ms | 26.0 ms | 26.0 ms |
| Reading the six pads | 1.5 ms | 1.3 ms | 1.2 ms | 18.6 ms |
| Game speed vs real time | 100% | 100% | 84% | 8.7% |
| Evaluating a 7-card poker hand | 0.21 ms | 0.18 ms | 1.42 ms | 42.0 ms |
| Memory allocated per frame | 0 B | 0 B (no heap) | 2 B | 10.4 KB |
| Whole benchmark run | 66 s | 54 s | 2.6 min | 42.5 min |
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.
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!".