亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么[]比list()快?

為什么[]比list()快?

FFIVE 2019-09-27 16:33:56
我最近比較了[]和的處理速度,并list()驚訝地發現它的[]運行速度是的三倍以上list()。我跑了相同的測試與{}和dict(),結果幾乎相同:[]和{}兩個花了大約0.128sec /百萬次,而list()和dict()大約花費每個0.428sec /萬次。為什么是這樣?不要[]和{}(可能()和'',太)立即傳回文字的一些空股票的份,而其明確命名同行(list(),dict(),tuple(),str())完全去創建一個對象,他們是否真的有元素?我不知道這兩種方法有何不同,但我很想找出答案。我在文檔中或SO上都找不到答案,而尋找空括號卻比我預期的要麻煩得多。通過分別調用timeit.timeit("[]")和timeit.timeit("list()"),和timeit.timeit("{}")和timeit.timeit("dict()")來比較列表和字典,以獲得計時結果。我正在運行Python 2.7.9。我最近發現“ 為什么True慢于if? ”比較了if Trueto 的性能,if 1并且似乎觸及了類似的文字對全局場景;也許也值得考慮。
查看完整描述

3 回答

?
拉莫斯之舞

TA貢獻1820條經驗 獲得超10個贊

因為[]和{}是文字語法。Python可以創建字節碼僅用于創建列表或字典對象:


>>> import dis

>>> dis.dis(compile('[]', '', 'eval'))

  1           0 BUILD_LIST               0

              3 RETURN_VALUE        

>>> dis.dis(compile('{}', '', 'eval'))

  1           0 BUILD_MAP                0

              3 RETURN_VALUE        

list()和dict()是單獨的對象。它們的名稱需要解析,必須包含堆棧以推入參數,必須存儲框架以供以后檢索,并且必須進行調用。這都需要更多時間。


對于空的情況,這意味著您至少要有一個LOAD_NAME(必須在全局名稱空間以及__builtin__模塊中進行搜索),后跟一個CALL_FUNCTION必須保留當前幀:


>>> dis.dis(compile('list()', '', 'eval'))

  1           0 LOAD_NAME                0 (list)

              3 CALL_FUNCTION            0

              6 RETURN_VALUE        

>>> dis.dis(compile('dict()', '', 'eval'))

  1           0 LOAD_NAME                0 (dict)

              3 CALL_FUNCTION            0

              6 RETURN_VALUE        

您可以使用以下命令分別計時名稱查找timeit:


>>> import timeit

>>> timeit.timeit('list', number=10**7)

0.30749011039733887

>>> timeit.timeit('dict', number=10**7)

0.4215109348297119

時間差異可能是字典哈希沖突。從調用這些對象的時間中減去這些時間,然后將結果與使用文字的時間進行比較:


>>> timeit.timeit('[]', number=10**7)

0.30478692054748535

>>> timeit.timeit('{}', number=10**7)

0.31482696533203125

>>> timeit.timeit('list()', number=10**7)

0.9991960525512695

>>> timeit.timeit('dict()', number=10**7)

1.0200958251953125

因此,1.00 - 0.31 - 0.30 == 0.39每1000萬次調用必須調用該對象花費了額外的幾秒鐘。


您可以通過將全局名稱別名為本地名稱來避免全局查找成本(使用timeit設置,綁定到名稱的所有內容都是本地名稱):


>>> timeit.timeit('_list', '_list = list', number=10**7)

0.1866450309753418

>>> timeit.timeit('_dict', '_dict = dict', number=10**7)

0.19016098976135254

>>> timeit.timeit('_list()', '_list = list', number=10**7)

0.841480016708374

>>> timeit.timeit('_dict()', '_dict = dict', number=10**7)

0.7233691215515137

但您永遠無法克服這些CALL_FUNCTION成本。


查看完整回答
反對 回復 2019-09-27
?
慕尼黑8549860

TA貢獻1818條經驗 獲得超11個贊

list()需要全局查找和函數調用,但需要[]編譯為一條指令??吹剑?/p>


Python 2.7.3

>>> import dis

>>> print dis.dis(lambda: list())

  1           0 LOAD_GLOBAL              0 (list)

              3 CALL_FUNCTION            0

              6 RETURN_VALUE        

None

>>> print dis.dis(lambda: [])

  1           0 BUILD_LIST               0

              3 RETURN_VALUE        

None


查看完整回答
反對 回復 2019-09-27
?
守著星空守著你

TA貢獻1799條經驗 獲得超8個贊

因為list是一個功能轉化說一個字符串列表對象,而[]用于創建一個列表蝙蝠。嘗試一下(可能對您更有意義):


x = "wham bam"

a = list(x)

>>> a

["w", "h", "a", "m", ...]


y = ["wham bam"]

>>> y

["wham bam"]

為您提供包含您所輸入內容的實際列表。


查看完整回答
反對 回復 2019-09-27
  • 3 回答
  • 0 關注
  • 830 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號