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.deme...@ugent.be> wrote: > Hello all, > > As discussed in some other threads ([1], [2]), we should discuss the > METH_FASTCALL 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 LOAD_GLOBAL 0 (g) > 2 LOAD_FAST 0 (x) > 4 LOAD_FAST 1 (y) > 6 LOAD_CONST 1 (12) > 8 CALL_FUNCTION 3 > 10 RETURN_VALUE > > A C array can also easily and efficiently be handled by the C function > receiving it. So I consider this uncontroversial. > > The convention for METH_FASTCALL|METH_KEYWORDS 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 LOAD_GLOBAL 0 (f) > 2 LOAD_FAST 0 (x) > 4 LOAD_FAST 1 (y) > 6 LOAD_FAST 2 (z) > 8 LOAD_CONST 1 (('foo', 'bar')) > 10 CALL_FUNCTION_KW 3 > 12 RETURN_VALUE > > This is pretty clever: it exploits the fact that ('foo', 'bar') is a > constant tuple stored in f.__code__.co_consts. 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 > METH_FASTCALL. 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@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)
_______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com