Почему функция 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__
включает поиск по запросу