TL;DR. why is the code at the bottom so dramatically slow compared to Damien's?
context:
---
I've watched this very interesting talk by Damien George https://www.youtube.com/watch?v=hHec4qL ... el=PyConAU.
It shows an easy performance test for rapidly blinking an LED in micropython.
Initial code, that basically anyone would judge be be "OK" code runs at around 50khz which is slow.
With a few easy tricks this can be easily increased to 150khz (see result of iteration 3 at timestamp 20:22)
---
I've recreated the tests to see how they perform on my esp32 and the results are very similar:
test1: 4.959 sec, 24.794 usec/blink : 40.33 kblinks/sec
test3: 0.923 sec, 4.614 usec/blink : 216.74 kblinks/sec
now I've got a real life use case for a controller which has to do three things simultaneously:
1. expose an HTTP api with endpoints to control/read several sensors.
2. run some logic which regulates a few outputs based on sensor readings.
3. relay info with MQTT to a remote server
Obviously, coming from a java background, I've spun up a webserver (picoweb) and have created a +- 20 classes for various sensors and an MQTT client. All this works now, and the initial POC is sort of complete.... next up is improving upon it.
I wanted to learn about the performance implications uasyncio has on all of this. so I recreated Damien's test3, made it asynchronous and popped in a single sleep_ms(0) to see what would happen. The results were dramatic:
test7: 116.883 sec, 584.416 usec/blink : 1.74 kblinks/sec
I did expect this to run slower, but not 127 times slower. I'd like to know what you all think about this.
Is a test like this relevant? Can we improve upon this further without resorting to a viper-like solution?
Code: Select all
import time
from machine import Pin
import uasyncio
class SpecialPin():
PIN = 2
def __init__(self):
self.led = Pin(self.PIN, Pin.OUT)
self.on = self.led.on
self.off = self.led.off
led = SpecialPin()
N = 200_000
async def blink_simple(n):
on = led.on
off = led.off
r = range(n)
sleep = uasyncio.sleep_ms
for i in r:
on()
await sleep(0)
off()
async def time_it(f, n):
ticks_us = time.ticks_us
t0 = ticks_us()
await f(n)
t1 = ticks_us()
dt = time.ticks_diff(t1, t0)
fmt = '{:5.3f} sec, {:6.3f} usec/blink : {:8.2f} kblinks/sec'
print(fmt.format(dt * 1e-6, dt / N, N / dt * 1e3))
uasyncio.run(time_it(blink_simple, N))