-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enable built-ins compile for all boards #8687
Conversation
@RetiredWizard pinging for interest. global crun
try:
from builtins import compile
def crun(code: str) -> None:
exec(compile(code, "", "exec"))
except ImportError:
def crun(code: str) -> None:
exec(code) |
I fully finished the code to use The speedup is most apparent on the slower boards. c3 and regular esp32 became much more responsive. |
I would never have predicted a performance improvement from this. I can see why if you can cache the result of compile() and use it multiple times it could make a difference. I made some benchmark code and ran it on the unix port on my desktop computer (amd64) import time
n = 100_000
def timeit(title, f):
t0 = time.time()
for _ in range(n): f()
t1 = time.time()
dt = t1 - t0
print(f"{title:<20}: {dt:8.3f}")
def crun(s):
return exec(compile(s, "", "exec"))
codestr = "sum(range(100))"
code = compile(codestr, "", "exec")
timeit("exec", lambda: exec(codestr))
timeit("compile", lambda: compile(codestr, "", "exec"))
timeit("crun", lambda: crun(codestr))
timeit("code", lambda: exec(code)) typical results:
|
I swapped the exec with exec(compile()) in PyDOS. I haven't run any benchmarks but PyDOS doesn't seem to run much different. I have been testing on an S3 so I'll give the C3/ESP32 chips a try as well but PyDOS actually ran pretty well on those chips. I don't think I fully understand how the compile command should be used. PyDOS only executes a single python line at a time so I'm not sure I see where the speedup comes from. |
Still on the ESP32-S3, I decided to try timing a program: Running with exec(compile())
Running with just exec()
After re-testing both the exec(compile()) and exec() methods ran in 8 seconds. |
First of all, applications like ljinux are python scripts for the most part, not shell scripts. Let's spice up the code example and run it on C3.
C3 Results:
This is because of the interpreter. |
After some Discord discussions will @bill88t I was really confused by my earlier benchmark results and re-tested. Upon re-testing the compile option ran in 8 seconds rather than the 33 seconds I got earlier. I was using web workflow to move some files back and forth and was seeing issues with the web workflow apparently locking up the serial REPL and possibly crashing the WiFi interface. I haven't been able to isolate for a reproducible issue yet but I suspect it was WiFi issues that slowed down the earlier Compile test. |
I too made an oopsie with my testing (today it's borked tests day apparently). Old code (fixed):
Results (S3):
Newer tests: from time import monotonic
n = 2
def timeit(title, f):
t0 = monotonic()
for _ in range(n): f()
dt = monotonic() - t0
print(f"{title:<10}: {dt}s")
codestr = """
a = 0
for i in range(100):
b = 0
for i in range(100000):
b += i
"""
code = compile(codestr, "", "exec")
timeit("compile", lambda: compile(codestr, "", "exec"))
timeit("code", lambda: exec(code))
timeit("exec", lambda: exec(codestr)) Results (S3):
I actually have no idea what is going on. I drafted and undrafted cause I was attempting to enable native emitters and stuff. In any case, the function works. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's do this for all ports or none. There's no reason to limit it to one port.
Briefly tested on nrf and rp2. I can't test the others, since I don't have any. |
I ran a couple quick tests on the SAMD51 and mimxrt10xx. I didn't run any benchmarks and didn't notice any speed differences but the build seemed to work fine. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok with me!
This enables builtins.compile() for all espressif boards.
This is currently in draft as I want to run more tests and see how it affects storage space.I have already implemented some basic compilation support within ljinux which heavily relies on
exec
and the results are pretty impressive.However since I still haven't made a benchmark, I have no numbers to present.
I suggest as you try for yourselves.
I want to enable this on more and more ports, but I plan on doing it in different PRs, one step at a time.
If we end up enabling it on everything, then we can just revert the per-port PRs and enable it globally.