Ideas for improving performance of function calls
See original GitHub issueI saw that simple function calls in Brython take around 5x the time of CPython, so I looked into it a bit to see if there were some quick ways to speed it up. I found a few things that together led to a 10x speedup. I’m not sure if two of them are safe, so I’m just listing them here instead of making a PR.
-
Add
if(frame[1].$has_yield_in_cm){
test around the call toexit_ctx_managers_in_generators
in$B.leave_frame_exec
. This saves a ton of time (when you are running inside of anexec
), and is analogous to the code in$B.leave_frame
. Hopefully it is possible to do this, but I don’t know for sure. -
Every function body contains this line
$locals.__annotations__ = _b_.dict.$factory()
, but I don’t think it is possible to annotate local variables inside the function, so it is never used. Can it be removed? -
In
$B.leave_frame
, remove the call to$B.del_exc
and addframe[1].$current_exception = undefined
aftervar frame = $B.frames_stack.pop()
. -
In
$B.enter_frame
, returnnull
everywhere you currently use_b_.None
, and change the autogenerated trace code fromif($locals.$f_trace !== _b_.None){$B.trace_line()}
toif($locals.$f_trace){$B.trace_line()}
. This didn’t make nearly as large a difference as the first three, but it’s a simple change that also reduces the size of the generated code, so it still seems worth doing.
Thanks for taking a look at these!
Issue Analytics
- State:
- Created 3 years ago
- Comments:11 (11 by maintainers)
Top GitHub Comments
You can specify annotations on local variables, but I believe that they are not available at runtime (from PEP 526):
Looks good to me! When I run the benchmark named “function call” using http://localhost:8000/speed on the master branch, it takes 1900-2000ms for 1,000,000 calls to f(). When I run it on the function_call_speed branch, it takes 150ms. I disabled caching in my browser and cleared local storage and indexed DB between runs.
In CPython, I see that
__annotations__
inside a function seems to refer to the module level__annotations__
, and I think this will continue to work in Brython:CPython 3.8.0 output: