Somewhat predictably, my Parallel MicroPython Benchmarking thing got out of hand, and I’ve been scrabbling around jamming the benchmark code on every MicroPython board I can find.
So despite WordPress’s best efforts in thwarting me from having a table here, my results are as follows, from fastest to slowest:
Board | Interpreter | CPU @ Frequency / MHz | Time / s |
---|---|---|---|
DevEBox STM32H7xx | micropython 1.20.0 | STM32H743VIT6 @ 400 | 3.7 |
Metro M7 | micropython 1.24.1 | MIMXRT1011DAE5A @ 500 | 4.3 |
S3 PRO | micropython 1.25.0.preview | ESP32S3 @ 240 | 8.9 |
Raspberry Pi Pico 2 W | micropython 1.25.0.preview | RP2350 @ 150 | 10.3 |
ItsyBitsy M4 Express | micropython 1.24.1 | SAMD51G19A @ 120 | 12.3 |
pyboard v1.1 | micropython 1.24.1 | STM32F405RG @ 168 | 13.0 |
C3 mini | micropython 1.25.0.preview | ESP32-C3FH4 @ 160 | 13.2 |
HUZZAH32 – ESP32 | micropython 1.24.1 | ESP32 @ 160 | 15.4 |
S2 mini | micropython 1.25.0.preview | ESP32-S2FN4R2 @ 160 | 17.4 |
Raspberry Pi Pico W | micropython 1.24.1 | RP2040 @ 125 | 19.8 |
WeAct BlackPill STM32F411CEU6 | micropython 1.24.0.preview | STM32F411CE @ 96 | 21.4 |
W600-PICO | micropython 1.25.0.preview | W600-B8 @ 80 | 30.7 |
LOLIN D1 mini | micropython 1.24.1 | ESP8266 @ 80 | 45.6 |
Yes, I was very surprised that the DevEBox STM32H7 at 400 MHz was faster than the 500 MHz MIMXRT1011 in the Metro M7. What was even more impressive is that the STM32H7 board was doing all the calculations in double precision, while all the others were working in single.
As for the other boards, the ESP32 variants performed solidly, but the ESP8266 in last place should be retired. The Raspberry Pi Pico 2 W was fairly nippy, but the original Raspberry Pi Pico is still a lowly Cortex-M0+, no matter how fast you clock it. The STM32F4 boards were slower than I expected them to be, frankly. And yay! to the plucky little W600: it comes in second last, but it’s the cheapest thing out there.
All of these benchmarks were made with the same code, but with two lines changed:
- The I2C specification, which is a minor syntax change for each board;
- The input trigger pin. Some boards like these as numbers, some take them as strings. Pro tip for W600 users: don’t use D0 for an input that’s tied to ground, unless you want the board to go into bootloader mode …
I’d hoped to run these tests on the SAMD21 little micro-controllers (typically 48 MHz Cortex-M0), but they don’t have enough memory for MicroPython’s framebuf module, so it’s omitted from the build. They would likely have been very slow, though.
In the spirit of fairness, I also benchmarked CircuitPython on a Arduino Nano RP2040 Connect, which has the same processor as a Raspberry Pi Pico:
Board | Interpreter | CPU @ Frequency / MHz | Time / s |
---|---|---|---|
Arduino Nano RP2040 Connect | circuitpython 9.2.3 | RP2040 @ 125 | 18.0 |
So it’s about 10% quicker than MicroPython, but I had to muck around for ages fighting with CircuitPython’s all-over-the-shop documentation and ninny syntax changes. For those that like that sort of thing, I guess that’s the sort of thing they like.