[Python-ideas] Ordering keyword dicts

Eric Snow ericsnowcurrently at gmail.com
Mon Jun 10 16:22:19 CEST 2013


On Mon, Jun 10, 2013 at 1:09 AM, Alexander Belopolsky
<alexander.belopolsky at gmail.com> wrote:
> I started experimenting with a patch on top
> of issue16991 which is essentially this:
>
>
> --- a/Python/ceval.c Mon Jun 10 02:24:00 2013 -0400
> +++ b/Python/ceval.c Mon Jun 10 02:58:38 2013 -0400
> @@ -3378,7 +3378,7 @@
>
>      /* Parse arguments. */
>      if (co->co_flags & CO_VARKEYWORDS) {
> -        kwdict = PyDict_New();
> +        kwdict = PyODict_New();
>          if (kwdict == NULL)
>              goto fail;
>          i = total_args;
> @@ -3441,7 +3441,7 @@
>                           keyword);
>              goto fail;
>          }
> -        PyDict_SetItem(kwdict, keyword, value);
> +        PyODict_SetItem(kwdict, keyword, value);
>          continue;
>        kw_found:
>          if (GETLOCAL(j) != NULL) {
>
> This was enough to get
>
>>>> def f(**kw): return kw
> ...
>>>> f(a=2, b=3)
> OrderedDict([('a', 2), ('b', 3)])

That is pretty cool.

>
> In this particular code path, checking for another flag should not cost
> anything in performance: even if compiler will not optimize it completely
> the flags will be in a register and at most the other check will cost a few
> CPU cycles and with no memory access.

Good.  From what I could see, there would be 7 calls that would change:

PyEval_EvalCodeEx()
   PyDict_New()
   PyDict_SetItem()

update_keyword_args()
   PyDict_New()
   PyDict_Copy()
   PyDict_SetItem()

ext_do_call()
   PyDict_New()
   PyDict_Update()

Each of these would switch on the flag on the function object.

-eric


More information about the Python-ideas mailing list