2013-11-30 6 views
15

В 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)) 

Demo link

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

+0

возможный дубликат [Профильные исполнения Len (комплект) в зависимости от набора. \ _ \ _ Len \ _ \ _() в Python 3] (http://stackoverflow.com/questions/8778691/profiled-performance-of-lenset-vs-set-len-in-python-3) –

+0

@GamesBrainiac Этот вопрос касается наблюдения * напротив *. – delnan

+1

Кроме того, точка использования 'setup' заключается в том, чтобы обеспечить синхронизацию только того, что вас интересует. Если вы хотите установить время' a' +, чтобы получить длину, это нормально, но вам не нужно У вас есть «настройка». – DSM

ответ

29

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

Атрибут .__len__ на встроенных объектах косвенно равен mapped to the same slot, и это косвенность (плюс поиск атрибута), которая занимает больше времени.

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

0

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

+3

Это ставит вопрос о том, как «len» может избежать поиска в dict, и я не думаю, что это особенно полезно OP (или любому другому, кто еще не знает, как это сделать), не объясняя это. – delnan

Смежные вопросы