Почему функция Python len работает быстрее, чем метод __len__?

В Python len - это функция, чтобы получить длину коллекции, вызвав метод __len__:

def len(x):
    return x.__len__()

Поэтому я ожидал бы, что прямой вызов __len__() будет по крайней мере таким быстрым, как len().

import timeit

setup = '''
'''

print (timeit.Timer('a="12345"; x=a.__len__()', setup=setup).repeat(10))
print (timeit.Timer('a="12345"; x=len(a)',      setup=setup).repeat(10))

Демо-ссылка

Но результаты тестирования с приведенным выше кодом показывают, что len() будет быстрее. Зачем?

Ответы

Ответ 1

Встроенная функция len() не ищет атрибут .__len__. Он ищет указатель tp_as_sequence, который, в свою очередь, имеет атрибут sq_length.

Атрибут .__len__ на встроенных объектах косвенно сопоставлен с одним и тем же слотом, и именно это направление (плюс поиск атрибута) занимает больше времени.

Для классов, определенных Python, объект type ищет метод .__len__, когда запрашивается sq_length.

Ответ 2

__len__ медленнее, чем len(), потому что __len__ включает поиск по запросу