[Python-Dev] On the METH_FASTCALL calling convention (original) (raw)
Victor Stinner vstinner at redhat.com
Fri Jul 6 18:26:16 EDT 2018
- Previous message (by thread): [Python-Dev] On the METH_FASTCALL calling convention
- Next message (by thread): [Python-Dev] On the METH_FASTCALL calling convention
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Hi,
I designed FASTCALL with the help of Serhiy for keywords. I prepared a long email reply, but I found an opportunity for optimisation on **kwargs and I need time to see how to optimize it.
Maybe there is a need for passing **kwargs as a dict at C level, but use FASTCALL for positional arguments? I only know dict.update() which would benefit of that. All other functions are fine with FASTCALL for keywords.
Victor
Le vendredi 6 juillet 2018, Guido van Rossum <guido at python.org> a écrit :
I'm not the world's leading expert on Python bytecode anymore, but unless there's something I'm missing your conclusion looks eminently reasonable, and so I expect you'll get very little traction on this thread. (If you had wanted to get a megathread you should have written "FASTCALL considered harmful". :-)
I think there was one person in another thread (INADA Naoki?) who thought METH_FASTCALL could use improvements. Maybe that person can write back to this thread? Or perhaps Victor Stinner (who seems to have touched it last) has a suggestion for what could be improved about it? --Guido On Thu, Jul 5, 2018 at 7:55 AM Jeroen Demeyer <J.Demeyer at ugent.be> wrote:
Hello all, As discussed in some other threads ([1], [2]), we should discuss the METHFASTCALL calling convention. For passing only positional arguments, a C array of Python objects is used, which is as fast as it can get. When the Python interpreter calls a function, it builds that C array on the interpreter stack: >>> from dis import dis >>> def f(x, y): return g(x, y, 12) >>> dis(f) 1 0 LOADGLOBAL 0 (g) 2 LOADFAST 0 (x) 4 LOADFAST 1 (y) 6 LOADCONST 1 (12) 8 CALLFUNCTION 3 10 RETURNVALUE A C array can also easily and efficiently be handled by the C function receiving it. So I consider this uncontroversial. The convention for METHFASTCALL|METHKEYWORDS is that keyword names are passed as a tuple and keyword values in the same C array with positional arguments. An example: >>> from dis import dis >>> def f(x, y, z): return f(x, foo=y, bar=z) >>> dis(f) 1 0 LOADGLOBAL 0 (f) 2 LOADFAST 0 (x) 4 LOADFAST 1 (y) 6 LOADFAST 2 (z) 8 LOADCONST 1 (('foo', 'bar')) 10 CALLFUNCTIONKW 3 12 RETURNVALUE This is pretty clever: it exploits the fact that ('foo', 'bar') is a constant tuple stored in f.code.coconsts. Also, a tuple can be efficiently handled by the called code: it is essentially a thin wrapper around a C array of Python objects. So this works well. The only case when this handling of keywords is suboptimal is when using **kwargs. In that case, a dict must be converted to a tuple. It looks hard to me to support efficiently both the case of fixed keyword arguments (f(foo=x)) and a keyword dict (f(**kwargs)). Since the former is more common than the latter, the current choice is optimal. In other words: I see nothing to improve in the calling convention of METHFASTCALL. I suggest to keep it and make it public as-is.
Jeroen. [1] https://mail.python.org/pipermail/python-dev/2018-June/153945.html [2] https://mail.python.org/pipermail/python-dev/2018-July/154251.html
Python-Dev mailing list Python-Dev at python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/guido%40python.org
-- --Guido van Rossum (python.org/~guido) -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.python.org/pipermail/python-dev/attachments/20180707/7f91d6d1/attachment.html>
- Previous message (by thread): [Python-Dev] On the METH_FASTCALL calling convention
- Next message (by thread): [Python-Dev] On the METH_FASTCALL calling convention
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]