Skip to content
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

Specialize FASTCALL for functions with positional-only parameters #73650

Closed
serhiy-storchaka opened this issue Feb 6, 2017 · 38 comments
Closed
Assignees
Labels
3.7 (EOL) end of life interpreter-core (Objects, Python, Grammar, and Parser dirs) performance Performance or resource usage

Comments

@serhiy-storchaka
Copy link
Member

BPO 29464
Nosy @rhettinger, @scoder, @vstinner, @skrah, @serhiy-storchaka, @timgraham
PRs
  • bpo-29464: Rename METH_FASTCALL to METH_FASTCALL|METH_KEYWORDS and make #1955
  • bpo-29464: Remove _PyArg_NoStackKeywords(). #2641
  • Files
  • fastcall-no-keywords.patch
  • fastcall-no-keywords-2.patch
  • fastcall-no-keywords-3.patch
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = 'https://github.com/serhiy-storchaka'
    closed_at = <Date 2017-07-10.12:51:42.598>
    created_at = <Date 2017-02-06.15:22:45.800>
    labels = ['interpreter-core', '3.7', 'performance']
    title = 'Specialize FASTCALL for functions with positional-only parameters'
    updated_at = <Date 2017-07-13.06:47:00.521>
    user = 'https://github.com/serhiy-storchaka'

    bugs.python.org fields:

    activity = <Date 2017-07-13.06:47:00.521>
    actor = 'vstinner'
    assignee = 'serhiy.storchaka'
    closed = True
    closed_date = <Date 2017-07-10.12:51:42.598>
    closer = 'serhiy.storchaka'
    components = ['Interpreter Core']
    creation = <Date 2017-02-06.15:22:45.800>
    creator = 'serhiy.storchaka'
    dependencies = []
    files = ['46544', '46558', '46699']
    hgrepos = []
    issue_num = 29464
    keywords = ['patch']
    message_count = 38.0
    messages = ['287143', '287146', '287150', '287151', '287152', '287155', '287156', '287176', '287199', '287231', '287238', '287253', '287259', '288992', '295169', '295170', '295174', '295176', '295177', '295178', '295785', '295789', '295791', '296819', '296901', '297136', '297606', '297748', '298030', '298031', '298061', '298227', '298230', '298232', '298258', '298264', '298265', '298268']
    nosy_count = 6.0
    nosy_names = ['rhettinger', 'scoder', 'vstinner', 'skrah', 'serhiy.storchaka', 'Tim.Graham']
    pr_nums = ['1955', '2641']
    priority = 'low'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'performance'
    url = 'https://bugs.python.org/issue29464'
    versions = ['Python 3.7']

    @serhiy-storchaka
    Copy link
    Member Author

    Proposed patch renames METH_FASTCALL to METH_FASTCALL|METH_KEYWORDS and makes bare METH_FASTCALL be used for functions with positional-only parameters. This eliminates small cost that these functions pay for handling empty keywords: calling _PyStack_UnpackDict() and _PyArg_NoStackKeywords(), passing kwnames. This also can slightly reduce stack consumption.

    @serhiy-storchaka serhiy-storchaka added 3.7 (EOL) end of life interpreter-core (Objects, Python, Grammar, and Parser dirs) performance Performance or resource usage labels Feb 6, 2017
    @vstinner
    Copy link
    Member

    vstinner commented Feb 6, 2017

    Proposed patch renames METH_FASTCALL to METH_FASTCALL|METH_KEYWORDS and makes bare METH_FASTCALL be used for functions with positional-only parameters.

    While I tried to keep everything related to FASTCALL private, it seems like Cython uses some FASTCALL features. I don't know which ones exactly. Well, if only one project in the world uses FASTCALL, we can help them to support such backward incompatible change ;-)

    This eliminates small cost that these functions pay for handling empty keywords: calling _PyStack_UnpackDict() and _PyArg_NoStackKeywords(), passing kwnames.

    My idea when I designed FASTCALL was to move code to parse arguments in the function body rather than in _PyCFunction_FastCallKeywords(), and to have a single calling function METH_FASTCALL, rather than two (METH_FASTCALL and METH_FASTCALL|METH_KEYWORDS).

    The long term plan is also to support passing arguments by keyword in more functions. IMHO many functions don't accept keywords for technical reasons, but once we converted a module, function or type to Argument Clinic, it becomes trivial to accept keywords. If most functions accept keywords, I'm not sure that having a special case for positional-only is still worth it. But this plan was before I had discussions on supporting keywords in unicode methods. In fact, it's deliberate to not accept keywords in many functions or methods.

    Well, when I see your patch, I see that it removes a lot of code. So it's likely to be a good idea :-)

    This also can slightly reduce stack consumption.

    You mean the removal of the "PyObject *kwnames" for METH_FASTCALL (positional arguments only)? Do you have an idea of the stack usage? Try maybe testcapi_stacksize.patch of the issue bpo-28870? It would help to take a decision on this change.

    @serhiy-storchaka
    Copy link
    Member Author

    We can avoid breaking backward compatibility and introduce new call method METH_FASTCALL_NO_KEYWORDS. But combining existing flags looks better to me. FASTCALL is not a part of stable ABI.

    I still didn't do any benchmarking or stack usage measurements.

    @vstinner
    Copy link
    Member

    vstinner commented Feb 6, 2017

    I still didn't do any benchmarking or stack usage measurements.

    I'm running benchmarks on the speed-python server.

    @skrah
    Copy link
    Mannequin

    skrah mannequin commented Feb 6, 2017

    Adding Stefan Behnel, perhaps Cython doesn't need backwards compatibility.

    @vstinner
    Copy link
    Member

    vstinner commented Feb 6, 2017

    I measured the stack consumption, it's not better. But I created the issue bpo-29465 "Add _PyObject_FastCall() to reduce stack consumption" which would allow to reduce the stack consumption with this patch.

    @vstinner
    Copy link
    Member

    vstinner commented Feb 6, 2017

    We can avoid breaking backward compatibility and introduce new call method METH_FASTCALL_NO_KEYWORDS. But combining existing flags looks better to me. FASTCALL is not a part of stable ABI.

    If we decide that having two FASTCALL calling convention, I prefer what you proposed: METH_FASTCALL (pos only) and METH_FASTCALL|METH_KEYWORDS (pos+kw). As you wrote, I like reusing the existing METH_KEYWORDS flag, it reduces the surprises if someone ports existing code using METH_VARARGS and METH_VARARGS|METH_KEYWORDS.

    @vstinner
    Copy link
    Member

    vstinner commented Feb 6, 2017

    Hum, benchmark results don't seem good. There is probably a performance bug somewhere. I should investigate further to analyze these results. M aybe combined with the issue bpo-29465, results will be better.

    haypo@speed-python$ python3 -m perf compare_to ~/benchmarks/2017-02-06_07-15-default-e06af4027546.json fastcall-no-keywords_ref_e06af4027546.json -G --min-speed=5

    Slower (19):

    • unpickle_list: 6.36 us +- 0.11 us -> 8.08 us +- 0.14 us: 1.27x slower (+27%)
    • pickle_list: 7.53 us +- 0.41 us -> 8.62 us +- 0.49 us: 1.14x slower (+14%)
    • crypto_pyaes: 199 ms +- 2 ms -> 226 ms +- 2 ms: 1.13x slower (+13%)
    • pickle: 22.1 us +- 0.3 us -> 24.9 us +- 0.3 us: 1.12x slower (+12%)
    • nbody: 233 ms +- 2 ms -> 260 ms +- 2 ms: 1.12x slower (+12%)
    • xml_etree_iterparse: 179 ms +- 4 ms -> 198 ms +- 5 ms: 1.11x slower (+11%)
    • telco: 14.7 ms +- 0.3 ms -> 16.3 ms +- 0.5 ms: 1.11x slower (+11%)
    • pickle_dict: 56.6 us +- 4.3 us -> 62.7 us +- 4.7 us: 1.11x slower (+11%)
    • pidigits: 291 ms +- 1 ms -> 319 ms +- 1 ms: 1.10x slower (+10%)
    • scimark_fft: 662 ms +- 10 ms -> 717 ms +- 8 ms: 1.08x slower (+8%)
    • scimark_monte_carlo: 207 ms +- 4 ms -> 224 ms +- 6 ms: 1.08x slower (+8%)
    • regex_v8: 43.7 ms +- 0.6 ms -> 47.0 ms +- 0.3 ms: 1.08x slower (+8%)
    • float: 238 ms +- 3 ms -> 254 ms +- 4 ms: 1.07x slower (+7%)
    • xml_etree_parse: 242 ms +- 5 ms -> 257 ms +- 9 ms: 1.06x slower (+6%)
    • raytrace: 1.04 sec +- 0.01 sec -> 1.11 sec +- 0.01 sec: 1.06x slower (+6%)
    • unpickle: 30.0 us +- 0.3 us -> 31.8 us +- 0.3 us: 1.06x slower (+6%)
    • go: 493 ms +- 7 ms -> 520 ms +- 6 ms: 1.05x slower (+5%)
    • scimark_sparse_mat_mult: 8.24 ms +- 0.14 ms -> 8.69 ms +- 0.14 ms: 1.05x slower (+5%)
    • chaos: 234 ms +- 2 ms -> 246 ms +- 4 ms: 1.05x slower (+5%)

    Faster (2):

    • chameleon: 21.9 ms +- 0.2 ms -> 20.7 ms +- 0.3 ms: 1.06x faster (-5%)
    • sympy_expand: 949 ms +- 12 ms -> 899 ms +- 11 ms: 1.06x faster (-5%)

    Benchmark hidden because not significant (43): (...)

    @scoder
    Copy link
    Contributor

    scoder commented Feb 7, 2017

    Thanks for asking. Cython doesn't use METH_FASTCALL yet, so this doesn't introduce any problems.

    Generally speaking, if Cython generated user code stops working with a new CPython version, we expect people to regenerate their code with the newest Cython version to fix it, so this kind of internal incompatibility is usually reparable by adapting Cython appropriately.

    @serhiy-storchaka
    Copy link
    Member Author

    There was a bug in previous patch. The signature of generated by Argument Clinic functions was not changed. Updated patch fixes this bug and also fixes the use of fast call in deque methods.

    @vstinner
    Copy link
    Member

    vstinner commented Feb 7, 2017

    Ok, so I looked again at your change: fastcall-no-keywords-2.patch LGTM,
    I like the idea!

    Since your patch is huge, I expect that it will be a pain to rebase it. I
    suggest you to push it as soon as possible, to avoid conflicts. I will rework
    my issue bpo-29465 patch once this issue is done.

    According to the number of modified functions and files, not accepting keyword
    arguments is very common, and so it is annoying to have to call
    _PyArg_NoStackKeywords() in each function. Avoiding the "PyObject *kwnames" can
    also reduces the stack consumption per call, especially in long call stacks.

    At least my assumption that almost no function will accept only positional
    arguments is plain wrong :-) In practice, it's more the opposite!

    I checked quickly fastcall-no-keywords-2.patch stack usage and performance.
    It seems non significant, but I'm not surprised, it isn't really the purpose
    of the change. IMHO the purpose of the change is more to simplify the code,
    avoid to duplicate _PyArg_NoStackKeywords() everywhere, and only check
    keyword arguments at one place.

    For stack consumption and performances, I got good results on my issue bpo-29465
    which adds a new _PyObject_FastCall() function. IMHO this function fits well
    with your new METH_FASTCALL (no keyword argument)! If we combine both changes,
    we can get something very good ;-)

    @Stefan Behnel: Thank you for you reply. So the backward compatibility was a
    fake issue, and we are free to modify METH_FASTCALL. Anyway, *if* someone uses
    METH_FASTCALL, IMHO it will be easy to update his/her code and add #ifdef on
    the Python version if needed. Again, as Serhiy wrote, METH_FASTCALL is out of
    the stable ABI, so we are safe on our warranties.

    @serhiy-storchaka
    Copy link
    Member Author

    The major part of the patch is generated by Argument Clinic. It is not a pain to rebase it. I prefer to delay pushing the patch until we prove its usefulness, because the cost of this change is not zero. Is it a stopper for bpo-29465?

    @serhiy-storchaka serhiy-storchaka self-assigned this Feb 7, 2017
    @vstinner
    Copy link
    Member

    vstinner commented Feb 7, 2017

    Serhiy Storchaka: "I prefer to delay pushing the patch until we prove its usefulness, because the cost of this change is not zero. Is it a stopper for bpo-29465?"

    Ok. No, it's not a blocker for my issue bpo-29465.

    About usefulness, I'm curious of the performance impact on this patch on top of the issue bpo-29465. I tried to run a benchmark, but my tooling only works well with a single patch, not with two patches, and one based on the other. Moreover, our patches are in conflict.

    So it seems like the issue bpo-29465 makes Python faster and uses less stack memory, I suggest to first focus on that one, and then rebase your patch on top of that. What do you think?

    @rhettinger
    Copy link
    Contributor

    Proposed patch renames METH_FASTCALL to METH_FASTCALL|METH_KEYWORDS
    and makes bare METH_FASTCALL be used for functions with
    positional-only parameters.

    +1

    @scoder
    Copy link
    Contributor

    scoder commented Jun 5, 2017

    I looked up this change again and was surprised that it still wasn't applied. It feels to me that it makes sense already for reasons of consistency. Any time frame for changing it? I'd like to use METH_FASTCALL in Cython in a future-proof way.

    @rhettinger
    Copy link
    Contributor

    Proposed patch renames METH_FASTCALL to METH_FASTCALL|METH_KEYWORDS
    and makes bare METH_FASTCALL be used for functions with
    positional-only parameters. This eliminates small cost that
    these functions pay for handling empty keywords: calling
    _PyStack_UnpackDict() and _PyArg_NoStackKeywords(),
    passing kwnames. This also can slightly reduce stack
    consumption.

    +1 for all the reasons listed. These are very reasonable specializations. The empty keyword checks are really irritating for fine-grained functions.

    @skrah
    Copy link
    Mannequin

    skrah mannequin commented Jun 5, 2017

    I'd like to use METH_FASTCALL in Cython in a future-proof way.

    Also +1. Can we consider the API frozen after this issue or do we have to wait for bpo-29465 (or others)?

    @serhiy-storchaka
    Copy link
    Member Author

    Actually these arguments are pretty weak. The sole argument of consistency is weak itself. _PyArg_NoStackKeywords() is pretty cheap since implementing it as a macro. This change just moves the check from the implementation of functions to the calling place. Virtually all affected functions (320 vs 7) are generated by Argument Clinic, so this doesn't simplify the maintenance much. The only runtime effect is possible saving a register or few bytes on the stack and few CPU tacts for passing the kwnames argument (always NULL). But this depends on the compiler.

    I don't consider this API frozen still. I have other idea for passing keyword arguments and want to experiment with it.

    @serhiy-storchaka
    Copy link
    Member Author

    Victor, could you please rerun benchmarks and check whether this change cause performance degradation?

    @skrah
    Copy link
    Mannequin

    skrah mannequin commented Jun 5, 2017

    For third party projects who want to use FASTCALL the functions are not generated by AC. I didn't understand the reasoning why the consistency argument is weak.

    @vstinner
    Copy link
    Member

    Here are benchmark results. Sorry, but I'm not really convinced that this specialization is worth it.

    The change adds yet another calling convention where we already have METH_NOARG, METH_VARARGS, METH_O, METH_NOARG | METH_KEYWORDS, METH_FASTCALL...

    I'm ok to add a new calling convention but only if it's faster on more benchmarks or if it uses much less memory. It doesn't seem to be the case with the current change.

    Differences of at least 5%:

    haypo@speed-python$ python3 -m perf compare_to /home/haypo/json/2017-06-09_08-18-master-ef8320cf6f09.json.gz ~/json/patch/2017-06-09_08-18-master-ef8320cf6f09-patch-1955.json.gz -G --min-speed=5 --table

    +-------------------------+--------------------------------------+-------------------------------------------------+
    | Benchmark | 2017-06-09_08-18-master-ef8320cf6f09 | 2017-06-09_08-18-master-ef8320cf6f09-patch-1955 |
    +=========================+======================================+=================================================+
    | spectral_norm | 283 ms | 263 ms: 1.08x faster (-7%) |
    +-------------------------+--------------------------------------+-------------------------------------------------+
    | scimark_lu | 294 ms | 314 ms: 1.07x slower (+7%) |
    +-------------------------+--------------------------------------+-------------------------------------------------+
    | scimark_sparse_mat_mult | 8.15 ms | 9.12 ms: 1.12x slower (+12%) |
    +-------------------------+--------------------------------------+-------------------------------------------------+

    Differences of at least 2%:

    haypo@speed-python$ python3 -m perf compare_to /home/haypo/json/2017-06-09_08-18-master-ef8320cf6f09.json.gz ~/json/patch/2017-06-09_08-18-master-ef8320cf6f09-patch-1955.json.gz -G --min-speed=2 --table

    +-------------------------+--------------------------------------+-------------------------------------------------+
    | Benchmark | 2017-06-09_08-18-master-ef8320cf6f09 | 2017-06-09_08-18-master-ef8320cf6f09-patch-1955 |
    +=========================+======================================+=================================================+
    | spectral_norm | 283 ms | 263 ms: 1.08x faster (-7%) |
    +-------------------------+--------------------------------------+-------------------------------------------------+
    | genshi_text | 73.1 ms | 70.5 ms: 1.04x faster (-3%) |
    +-------------------------+--------------------------------------+-------------------------------------------------+
    | scimark_monte_carlo | 209 ms | 201 ms: 1.04x faster (-3%) |
    +-------------------------+--------------------------------------+-------------------------------------------------+
    | raytrace | 1.05 sec | 1.02 sec: 1.02x faster (-2%) |
    +-------------------------+--------------------------------------+-------------------------------------------------+
    | regex_v8 | 40.3 ms | 41.4 ms: 1.03x slower (+3%) |
    +-------------------------+--------------------------------------+-------------------------------------------------+
    | json_dumps | 26.2 ms | 27.0 ms: 1.03x slower (+3%) |
    +-------------------------+--------------------------------------+-------------------------------------------------+
    | float | 207 ms | 215 ms: 1.04x slower (+4%) |
    +-------------------------+--------------------------------------+-------------------------------------------------+
    | crypto_pyaes | 199 ms | 207 ms: 1.04x slower (+4%) |
    +-------------------------+--------------------------------------+-------------------------------------------------+
    | scimark_fft | 644 ms | 675 ms: 1.05x slower (+5%) |
    +-------------------------+--------------------------------------+-------------------------------------------------+
    | scimark_lu | 294 ms | 314 ms: 1.07x slower (+7%) |
    +-------------------------+--------------------------------------+-------------------------------------------------+
    | scimark_sparse_mat_mult | 8.15 ms | 9.12 ms: 1.12x slower (+12%) |
    +-------------------------+--------------------------------------+-------------------------------------------------+

    @scoder
    Copy link
    Contributor

    scoder commented Jun 12, 2017

    I do not see this as a matter of performance but as a matter of usability. Basically, CPython could do just fine with just a single catch-all calling convention that packs all pos/kw arguments into C arguments and passes them over, leaving it entirely to the callee to handle them. Why does it not do that? Because it's cumbersome for the callee to analyse what kind of arguments it received and how to handle them.

    A surprisingly large number of functions take only a single argument, that's why METH_O exists. Many functions take no keyword arguments, that's why VARARGS and KEYWORDS are separate options. The same should apply to FASTCALL. Also with that, many implementors will not want to care about keyword arguments and would thus appreciate it if they didn't have to. Forcing them to test for keyword arguments and raising the correct error for it (with the correct and consistent message) seems an entirely unnecessary imposition.

    @vstinner
    Copy link
    Member

    Also with that, many implementors will not want to care about keyword arguments and would thus appreciate it if they didn't have to. Forcing them to test for keyword arguments and raising the correct error for it (with the correct and consistent message) seems an entirely unnecessary imposition.

    Ah, I took the habit of using Argument Clinic, so I don't have to both to thing anymore :-) But yes, writing manually the PyArg_XXX() code is boring and error-prone, I agree.

    @scoder
    Copy link
    Contributor

    scoder commented Jun 25, 2017

    Can the PR be applied then? It looks good to me.

    @vstinner
    Copy link
    Member

    Can the PR be applied then? It looks good to me.

    Go for it Serhiy. Even if it isn't faster today, we might find more optimizations later, at least in term of C stack consumption.

    Moreover, I understand perfectly the cost of having to parse arguments. Checking for keywords in the caller seems reasonable.

    This change breaks the backward compatibility with Python 3.6, right? I mean, code using METH_FASTCALL. I guess that only Cython extensions use it in the wild, and I expect that Cython extensions don't use the stable ABI but are recompiled for each 3.x release, so it should be fine in practice.

    @vstinner
    Copy link
    Member

    Oh, it seems like this change should help to use FASTCALL in the _decimal module: issue bpo-29301. Stefan doesn't want to use Argument Clinic.

    @serhiy-storchaka
    Copy link
    Member Author

    New changeset 6969eaf by Serhiy Storchaka in branch 'master':
    bpo-29464: Rename METH_FASTCALL to METH_FASTCALL|METH_KEYWORDS and make (bpo-1955)
    6969eaf

    @vstinner
    Copy link
    Member

    vstinner commented Jul 5, 2017

    New changeset 8207c17 by Victor Stinner in branch 'master':
    Revert "bpo-30822: Fix testing of datetime module." (bpo-2588)
    8207c17

    @serhiy-storchaka
    Copy link
    Member Author

    Josay noticed that _PyArg_NoStackKeywords() is not used anymore except for one place (_hashopenssl.c).

    Seems this is my oversign. Generated constructors in _hashopenssl.c use the METH_FASTCALL | METH_KEYWORDS calling method, but check that no keyword arguments are passed. They can now just use the METH_FASTCALL calling method. And _PyArg_NoStackKeywords() can be excluded from public header.

    @vstinner
    Copy link
    Member

    Let's remove this function which became useless.

    @serhiy-storchaka
    Copy link
    Member Author

    Removed _PyArg_NoStackKeywords() (7e60192).

    @timgraham
    Copy link
    Mannequin

    timgraham mannequin commented Jul 12, 2017

    Hi, I observed an error while trying to install numpy after 6969eaf.

    gcc: numpy/random/mtrand/mtrand.c
    numpy/random/mtrand/mtrand.c: In function ‘__Pyx_PyCFunction_FastCall’:
    numpy/random/mtrand/mtrand.c:44374:5: error: too many arguments to function ‘(struct PyObject * ()(struct PyObject *, struct PyObject **, Py_ssize_t))meth’
    return (
    ((__Pyx_PyCFunctionFast)meth)) (self, args, nargs, NULL);
    ^

    Is this a bug in Python or does it need to be fixed in numpy?

    @serhiy-storchaka
    Copy link
    Member Author

    I think you need to update Cython to a version that supports new FASTCALL call convention in 3.7. If the support of FASTCALL in Cython is optional try to disable it.

    @timgraham
    Copy link
    Mannequin

    timgraham mannequin commented Jul 12, 2017

    Thanks, I'm not sure what that means exactly but I added the note to numpy/numpy#9391. Perhaps a note in the Python release notes is warranted?

    @scoder
    Copy link
    Contributor

    scoder commented Jul 13, 2017

    For future reference, this change is supported by Cython 0.26 (which is currently close to release).

    @serhiy-storchaka
    Copy link
    Member Author

    Great!

    Are all uses of internal CPython details optional? I would disable them by default for alpha versions of CPython.

    @scoder
    Copy link
    Contributor

    scoder commented Jul 13, 2017

    Are all uses of internal CPython details optional?

    Well, what classifies as a "CPython detail" sometimes just becomes clear when other implementations don't have it. ;-)

    But yes, the C code that Cython generates selects alternative implementations based on some more or less generic C defines, e.g. CYTHON_COMPILING_IN_CPYTHON or CYTHON_USE_PYLONG_INTERNALS or CYTHON_ASSUME_SAFE_MACROS. We enable them based on the Python implementation and even users can disable them at need. Well, and then there are obviously tons of PY_VERSION_HEX specific special cases, such as this one.

    I would disable them by default for alpha versions of CPython.

    I don't see why. We track the CPython development via travis-CI and alpha versions make us aware of changes that we need to incorporate (or sometimes fight against ;-) ). These internals very rarely change across CPython releases (e.g. the PyLong type didn't really change since 3.0/2.7.0), and this one is really an exception. Excluding alpha versions would probably reduce our response time to these changes.

    @vstinner
    Copy link
    Member

    When I worked on FASTCALL, I wasn't sure that the whole project was worth
    it. Now I am more confident that it makes function calls faster:
    https://haypo.github.io/fastcall-microbenchmarks.html

    Stefan, Serhiy: would it be a good idea to make _PyObject_FastCall() and
    _PyObject_FastCallKeywords(), or also _PyObject_FastCallDict(), public? I
    expect complains from PyPy who will have to support METH_FASTCALL as well
    :-)

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    3.7 (EOL) end of life interpreter-core (Objects, Python, Grammar, and Parser dirs) performance Performance or resource usage
    Projects
    None yet
    Development

    No branches or pull requests

    4 participants