[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Python-Dev] On the METH_FASTCALL calling convention


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.


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
>> 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 at python.org
>> https://mail.python.org/mailman/listinfo/python-dev
>> Unsubscribe:
> --
> --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>