-
-
Notifications
You must be signed in to change notification settings - Fork 3k
[mypyc] Use faster METH_FASTCALL wrapper functions on Python 3.7+ #9894
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
Conversation
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.
LGTM, just one suggestion.
# This is because CPyArg_ParseStackAndKeywords format string requires | ||
# them grouped in that way. | ||
groups = make_arg_groups(real_args) | ||
reordered_args = reorder_arg_groups(groups) |
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.
These preparatory steps here are very similar to the legacy wrapper below. Would it make sense to factor them out in a helper?
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.
Refactored some of the shared code. I didn't share everything, since I'm planning further changes that may only be relevant for new-style wrapper functions.
Allocate a vectorcall function pointer as a struct field for native classes that include `__call__`, including nested functions. This lets us use METH_FASTCALL wrapper functions with `__call__` methods. See https://www.python.org/dev/peps/pep-0590/ for details of why we jump through these hoops. This makes the `nested_func` microbenchmark about 1.5x faster. Follow-up to #9894.
Implement faster argument parsing based on METH_FASTCALL on supported
Python versions.
Use
vgetargskeywordsfast
extracted from Python 3.9 with some modifications:*args
and**kwargs
The modifications are very similar to what we have in the old-style
argument parsing logic.
The legacy calling convention is still used for
__init__
and__call__
. I'll add__call__
support in a separate PR. I haven't looked into supporting__init__
yet.
Here are some benchmark results (on Python 3.8)
However, the above benchmarks are still slower when compiled. I'll continue
working on further improvements after this PR.
Fixes mypyc/mypyc#578.