首頁  >  文章  >  後端開發  >  疑難雜症 :Python [] 與 list() 哪一個快?為什麼快?快多少呢?

疑難雜症 :Python [] 與 list() 哪一個快?為什麼快?快多少呢?

coldplay.xixi
coldplay.xixi轉載
2020-10-26 18:02:111879瀏覽

#今天 python影片教學專欄為大家講解Python中所承擔的知識,但蘊藏著巨大的能量。

疑難雜症 :Python [] 與 list() 哪一個快?為什麼快?快多少呢?

#在日常使用Python的時候,我們需要經常創建一個列表,相信大家都已經熟練了吧?

# 方法一:使用成对的方括号语法list_a = []# 方法二:使用内置的 list()list_b = list()复制代码
上面的兩種寫法,你經常使用哪一個一個呢?是否思考過的差異呢?######讓它們我們開門見山,直接提交論文的問題吧:###兩種創建列表的[] 與list() 寫法,哪一個更快呢,為什麼會更快呢?############註:為了簡化問題,我們以空列表為例進行分析。關於列表的更多介紹與創建說明,可以查看本文文章######## ##1、 [​​] 是list() 的三倍快###### 對於第一題,使用###timeit###模組的timeit() 函數即可簡單地測出來算:# ##
>>> import timeit>>> timeit.timeit('[]', number=10**7)>>> timeit.timeit('list()', number=10**7)复制代码
############如上圖所示,在各自呼叫一千萬次的情況下,[]創建方式只花費了0.47秒,而列表( ) 創建方式要花費1.75秒,所以,星期六的星期六是之前的3.7 倍!######這就回答了創建剛才的問題:###空列表時,[] 剛才的list()快亮。##### #######註:timeit()函數的效率跟運行環境相關,每次執行結果會有微小差異。我在Python3.8版本實驗了幾次,整體來說上[] 速度是list( ) 的3 倍多一點。#########2、list() 比[] 執行步驟多######那麼,我們繼續來分析第二個問題:為什麼[] 會更快呢?######這次我們可以使用####dis####模組的dis() 函數,看看兩個執行的字節碼有何不同:## #
>>> from dis import dis>>> dis("[]")>>> dis("list()")复制代码
### #####

如上圖所示,[] 的字節碼有兩條指令(BUILD_LIST 與 RETURN_VALUE),而 list() 的字節碼有三條指令(LOAD_NAME、CALL_FUNCTION 與 RETURN_VALUE)。

這些指令代表什麼呢?該如何理解它們呢?

首先,對於 [],它是 Python 中的一組字面量(literal),像數字之類的字面量一樣,表示確切的固定值。

也就是說,Python 在解析到它時,就知道它要表示一個列表,因此會直接呼叫解釋器中建構列表的方法(對應 BUILD_LIST ),來建立列表,所以是一步到位。

而對於 list(),「list」只是一個普通的名稱,並不是字面量,也就是說解釋器一開始並不認識它。

因此,解釋器的第一步是要找到這個名稱(對應 LOAD_NAME)。它會按照一定的順序,在各個作用域中逐一查找(局部作用域--全域作用域--內建作用域),直到找到為止,找不到則會拋出NameError

解釋器看到「list」之後是一對圓括號,因此第二步是把這個名稱當作可調用物件來調用,即把它當成一個函數進行調用(對應 CALL_FUNCTION)。

因此,list() 在建立清單時,需要經過名稱尋找與函數呼叫兩個步驟,才能真正開始建立清單(註:CALL_FUNCTION 在底層還會有一些函式呼叫過程,才能走到跟BUILD_LIST 相通的邏輯,此處我們忽略不計)。

至此,我們就可以回答前面的問題了:因為 list() 涉及的執行步驟更多,因此它比 [] 要慢一些。

3、list() 的速度提升

看完前兩個問題的解答過程,你也許覺得還不夠過癮,而且可能覺得就算知道了這個冷知識,也不會有多大的幫助,似乎那微弱的提升顯得微不足道。

但是,我們Python貓出品的《Python為什麼》系列一直秉承著孜孜不倦的求知精神,是不可能放著這個問題不去回答的。

而且,由於有發散性思考的習慣,我還想到了另一個挺有意思的問題:list() 的速度能否提升呢?

我不久前寫過一篇文章正好討論到這個問題,也就是在剛剛發布的Python 3.9.0 版本中,它給list() 實現了更快的vectorcall 協議,因此執行速度會有一定的提升。

有興趣的同學可以到 Python 官網下載 3.9 版本。

根據我多輪的測試結果,在新版本中運行list() 一千萬次,耗時大概在1 秒左右,也就是[] 運行耗時的2 倍,相比於前面接近4 倍的數據,目前版本整體上是提升了不少。

至此,我們已回答完一連串的疑問,如果你覺得有收穫,請按讚支持!歡迎大家關注後續更多精彩內容。

相關免費學習推薦:python影片教學

以上是疑難雜症 :Python [] 與 list() 哪一個快?為什麼快?快多少呢?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.im。如有侵權,請聯絡admin@php.cn刪除