簡體   English   中英

為什么 Python 的 'len' 函數比 __len__ 方法快?

[英]Why is Python's 'len' function faster than the __len__ method?

在 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()更快。 為什么?

內置的len()函數不會查找.__len__屬性。 它查找tp_as_sequence指針 ,該指針又具有sq_length屬性

內置對象的.__len__屬性間接映射到同一個插槽 ,而間接(加上屬性查找)需要花費更多時間。

對於Python定義的類,所述type對象中查找.__len__的方法時sq_length被請求。

__len__len()慢,因為__len__涉及dict查找。

來自優秀的Python Object-Oriented Programming: Build可靠且可維護的面向對象的 Python 應用程序和庫, Steven F. Lott 和 Dusty Phillips 的第 4 版書籍

您可能想知道為什么這些對象沒有 length 屬性,而不必對它們調用函數。 從技術上講,他們確實如此。 len()將應用於的大多數對象都有一個名為__len__()的方法,該方法返回相同的值。 所以len(myobj)似乎調用myobj.__len__()

為什么我們應該使用len()函數而不是__len__()方法? 很明顯, __len__()是一個特殊的雙下划線方法,建議我們不要直接調用它。 對此必須有一個解釋。 Python 開發人員不會輕易做出這樣的設計決定。

主要原因是效率。 當我們調用對象的__len__()方法時,該對象必須在其命名空間中查找該方法,並且,如果特殊的__getattribute__()方法(每次訪問對象的屬性或方法時都會調用)是在那個對象上定義,它也必須被調用。 此外, __getattribute__()方法可能是為了做一些聰明的事情而編寫的,例如,拒絕讓我們訪問諸如__len__()類的特殊方法! len()函數不會遇到任何這種情況。 它實際上調用底層類的__len__()方法,因此len(myobj)映射到MyObj.__len__(myobj)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM