[Python-ideas] a sorting protocol dunder method?

Serhiy Storchaka storchaka at gmail.com
Mon Dec 4 08:50:31 EST 2017


04.12.17 13:06, Antoine Pitrou пише:
> On Mon, 4 Dec 2017 08:45:55 +0200
> Serhiy Storchaka <storchaka at gmail.com>
> wrote:
>> 04.12.17 01:06, Chris Barker пише:
>>> So: has this already been brought up and rejected?
>>
>> https://bugs.python.org/issue20632
>>
>>> Am I imagining the performance benefits?
>>
>> This will add an additional overhead. This will be even slower than
>> passing the key function, since you will need to look up the __key__
>> method in every item.
> 
> That is a reasonable objection.  However, looking up a tp_XXX slot is
> very cheap.

But introducing a new slot is not easy. This will increase the size of 
the type object, break binary compatibility. According to Stefan 
Behnel's researches (https://bugs.python.org/issue31336) the main time 
of the creation of a new type is spent on initializing slots. This cost 
will pay every Python program, even if it doesn't use the __key__ method.

There are many more common and important methods that don't have the 
corresponding slot (__length_hint__, __getstate__, __reduce__, __copy__, 
keys).

>> Yes, it is too special-case. I don't see any advantages in comparison
>> with defining the __lt__ method.
> 
> There are definitely advantages.  Sorting calls __lt__ for each
> comparison (that is, O(n log n) times) while __key__ would only be
> called once per item at the start (that is, O(n) times).

It will call __lt__ for each key comparison (the same O(n log n) times), 
but *in addition* it will call __key__ O(n) times. You can get the 
benefit only when times of calling __key__ is much smaller than the 
difference between times of calling item's __lt__ and key's __lt__, and 
maybe only for large lists. But why not just pass the key argument when 
you sort the large list?

>> It will be rather confusing if
>> different methods of sorting produce inconsistent order.
> 
> If __key__ is inconsistent with __lt__, it is the same error as making
> __lt__ inconsistent with __gt__.

If __key__ is consistent with __lt__, then we can just use __lt__, and 
don't introduce new special methods.

> And there could be a decorator that generates all comparison methods
> from __key__.

The decorator idea LGTM. But it doesn't need the special __key__ method. 
Just pass the key function as a decorator argument.

This idea was proposed more than 3.5 years ago. Is there a PyPI package 
that implements it?



More information about the Python-ideas mailing list