frozendict: an experiment

Inada Naoki songofacandy at gmail.com
Sat Jul 18 21:17:50 EDT 2020


On Sun, Jul 19, 2020 at 6:38 AM Marco Sulla
<Marco.Sulla.Python at gmail.com> wrote:
>
> On Sat, 18 Jul 2020 at 10:02, Inada Naoki <songofacandy at gmail.com> wrote:
>>
>> On Sat, Jul 18, 2020 at 7:05 AM Marco Sulla
>> <Marco.Sulla.Python at gmail.com> wrote:
>> > For what I know, CPython uses PyDictObject for kwargs. Since dicts are
>> > mutable, it's a problem to cache them properly.
>>
>> On caller side, Python doesn't use dict at all.
>> On callee side, dict is used for `**kwargs`.  But changing it to frozendict is
>> backward incompatible change.
>
>
> Not sure of what you mean with caller and callee. If you're talking about Python, I agree, kwargs must be dicts. But I was talking about CPython and PyDictObject, that is used internally for kwargs.
>

I am talking about CPython VM.  Caller is code calling Python.  Callee
is the function called.

Look at the caller side first:

# x.py
foo(a=1, b=2)

$ python3 -m dis x.py
  1           0 LOAD_NAME                0 (foo)
              2 LOAD_CONST               0 (1)
              4 LOAD_CONST               1 (2)
              6 LOAD_CONST               2 (('a', 'b'))
              8 CALL_FUNCTION_KW         2
             10 POP_TOP
             12 LOAD_CONST               3 (None)
             14 RETURN_VALUE

As you can see, dict is not created during calling a function.

On the other hand, if callee is defined as:

    def foo(a, b): ...

CPython VM doesn't create a dict at all.  If callee is defined as:

    def foo(**kwargs): ...

The kwargs is dict, of course.  And changing it to frozendict is not
backward compatible.

C function is similar.  If the C function is defined using
METH_KEYWORDS, keyword
arguments are passed as dict. If the C function is defined using METH_FASTCALL,
keyword arguments are passed as C array.


> On Sat, 18 Jul 2020 at 10:02, Inada Naoki <songofacandy at gmail.com> wrote:
>>
>> Currently, `for k,v in d.items()`
>> doesn't create
>> temporary list or set-like.
>> I think using "real object" is not good performance optimization.
>
>
> Well, this is true... but they create view objects that are quite slow.

Is it really slow?  It is just a thin wrapper object.  How is it slow compared
iter(list)?  Iterator is just a thin wrapper too.

Regards,
-- 
Inada Naoki  <songofacandy at gmail.com>


More information about the Python-list mailing list