<div dir="ltr"><div>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". :-)<br></div><div><br></div><div>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?</div><div><br></div><div>--Guido<br></div></div><br><div class="gmail_quote"><div dir="ltr">On Thu, Jul 5, 2018 at 7:55 AM Jeroen Demeyer <<a href="mailto:J.Demeyer@ugent.be">J.Demeyer@ugent.be</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello all,<br>
<br>
As discussed in some other threads ([1], [2]), we should discuss the <br>
METH_FASTCALL calling convention.<br>
<br>
For passing only positional arguments, a C array of Python objects is <br>
used, which is as fast as it can get. When the Python interpreter calls <br>
a function, it builds that C array on the interpreter stack:<br>
<br>
 >>> from dis import dis<br>
 >>> def f(x, y): return g(x, y, 12)<br>
 >>> dis(f)<br>
   1           0 LOAD_GLOBAL              0 (g)<br>
               2 LOAD_FAST                0 (x)<br>
               4 LOAD_FAST                1 (y)<br>
               6 LOAD_CONST               1 (12)<br>
               8 CALL_FUNCTION            3<br>
              10 RETURN_VALUE<br>
<br>
A C array can also easily and efficiently be handled by the C function <br>
receiving it. So I consider this uncontroversial.<br>
<br>
The convention for METH_FASTCALL|METH_KEYWORDS is that keyword *names* <br>
are passed as a tuple and keyword *values* in the same C array with <br>
positional arguments. An example:<br>
<br>
 >>> from dis import dis<br>
 >>> def f(x, y, z): return f(x, foo=y, bar=z)<br>
 >>> dis(f)<br>
   1           0 LOAD_GLOBAL              0 (f)<br>
               2 LOAD_FAST                0 (x)<br>
               4 LOAD_FAST                1 (y)<br>
               6 LOAD_FAST                2 (z)<br>
               8 LOAD_CONST               1 (('foo', 'bar'))<br>
              10 CALL_FUNCTION_KW         3<br>
              12 RETURN_VALUE<br>
<br>
This is pretty clever: it exploits the fact that ('foo', 'bar') is a <br>
constant tuple stored in f.__code__.co_consts. Also, a tuple can be <br>
efficiently handled by the called code: it is essentially a thin wrapper <br>
around a C array of Python objects. So this works well.<br>
<br>
The only case when this handling of keywords is suboptimal is when using <br>
**kwargs. In that case, a dict must be converted to a tuple. It looks <br>
hard to me to support efficiently both the case of fixed keyword <br>
arguments (f(foo=x)) and a keyword dict (f(**kwargs)). Since the former <br>
is more common than the latter, the current choice is optimal.<br>
<br>
In other words: I see nothing to improve in the calling convention of <br>
METH_FASTCALL. I suggest to keep it and make it public as-is.<br>
<br>
<br>
Jeroen.<br>
<br>
<br>
[1] <a href="https://mail.python.org/pipermail/python-dev/2018-June/153945.html" rel="noreferrer" target="_blank">https://mail.python.org/pipermail/python-dev/2018-June/153945.html</a><br>
[2] <a href="https://mail.python.org/pipermail/python-dev/2018-July/154251.html" rel="noreferrer" target="_blank">https://mail.python.org/pipermail/python-dev/2018-July/154251.html</a><br>
_______________________________________________<br>
Python-Dev mailing list<br>
<a href="mailto:Python-Dev@python.org" target="_blank">Python-Dev@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-dev" rel="noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/python-dev</a><br>
Unsubscribe: <a href="https://mail.python.org/mailman/options/python-dev/guido%40python.org" rel="noreferrer" target="_blank">https://mail.python.org/mailman/options/python-dev/guido%40python.org</a><br>
</blockquote></div><br clear="all"><br>-- <br><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature">--Guido van Rossum (<a href="http://python.org/~guido">python.org/~guido</a>)</div>