第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

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

用于創(chuàng)建集合的 Python 性能比較 - set() 與 {} 文字

用于創(chuàng)建集合的 Python 性能比較 - set() 與 {} 文字

紅糖糍粑 2021-09-28 20:48:32
以下的討論這個(gè)問題,讓我知道,所以我決定運(yùn)行一些測試和比較的創(chuàng)建時(shí)間set((x,y,z))與{x,y,z}在Python中創(chuàng)建集(我使用Python 3.7)。我使用time和比較了兩種方法timeit。兩者都與以下結(jié)果一致*:test1 = """my_set1 = set((1, 2, 3))"""print(timeit(test1))結(jié)果:0.30240735499999993test2 = """my_set2 = {1,2,3}"""print(timeit(test2))結(jié)果:0.10771795900000003所以第二種方法幾乎比第一種方法快 3 倍。這對我來說是一個(gè)非常令人驚訝的差異。set()以這種方式優(yōu)化 set 文字在方法上的性能在幕后發(fā)生了什么?在哪些情況下建議使用哪種方法?* 注意:我只顯示timeit測試結(jié)果,因?yàn)樗鼈兪窃谠S多樣本上取平均值的,因此可能更可靠,但測試time結(jié)果在兩種情況下顯示出相似的差異。編輯:我知道這個(gè)類似的問題,雖然它回答了我原來問題的某些方面,但并沒有涵蓋所有方面。問題中沒有解決集合,并且由于空集合在 python 中沒有文字語法,我很好奇使用文字創(chuàng)建集合與使用該set()方法有何不同(如果有的話)。另外,我想知道的是如何處理的元組參數(shù)中set((x,y,z)會在幕后,什么是運(yùn)行時(shí)可能產(chǎn)生的影響。Coldspeed 的出色回答幫助解決了問題。
查看完整描述

1 回答

?
溫溫醬

TA貢獻(xiàn)1752條經(jīng)驗(yàn) 獲得超4個(gè)贊

(這是對現(xiàn)在已從最初問題中編輯出來的代碼的回應(yīng))您忘記在第二種情況下調(diào)用函數(shù)。進(jìn)行適當(dāng)?shù)男薷?,結(jié)果如預(yù)期:


test1 = """

def foo1():

     my_set1 = set((1, 2, 3))

foo1()

"""    

timeit(test1)

# 0.48808742000255734

test2 = """

def foo2():

    my_set2 = {1,2,3}

foo2()

"""    

timeit(test2)

# 0.3064506609807722

現(xiàn)在,時(shí)間差異的原因是因?yàn)閟et()函數(shù)調(diào)用需要查找符號表,而{...}集合構(gòu)造是語法的人工制品,并且速度要快得多。


觀察反匯編的字節(jié)碼時(shí),差異很明顯。


import dis


dis.dis("set((1, 2, 3))")

  1           0 LOAD_NAME                0 (set)

              2 LOAD_CONST               3 ((1, 2, 3))

              4 CALL_FUNCTION            1

              6 RETURN_VALUE

dis.dis("{1, 2, 3}")

  1           0 LOAD_CONST               0 (1)

              2 LOAD_CONST               1 (2)

              4 LOAD_CONST               2 (3)

              6 BUILD_SET                3

              8 RETURN_VALUE

在第一種情況下,函數(shù)調(diào)用是由CALL_FUNCTION元組上的指令進(jìn)行的(1, 2, 3)(它也有自己的開銷,雖然很小——它通過 加載為常量LOAD_CONST),而在第二條指令中只是一個(gè)BUILD_SET調(diào)用,這更多高效的。


回復(fù):您關(guān)于元組構(gòu)建所需時(shí)間的問題,我們認(rèn)為這實(shí)際上可以忽略不計(jì):


timeit("""(1, 2, 3)""")

# 0.01858693000394851


timeit("""{1, 2, 3}""")

# 0.11971827200613916

元組是不可變的,因此編譯器通過將其作為常量加載來優(yōu)化此操作——這稱為常量折疊(您可以從LOAD_CONST上面的指令中清楚地看到這一點(diǎn)),因此所花費(fèi)的時(shí)間可以忽略不計(jì)。這在集合中看不到,因?yàn)樗鼈兪强勺兊模ǜ兄x@user2357112 指出這一點(diǎn))。


對于更大的序列,我們看到了類似的行為。{..}與set()必須從生成器構(gòu)建集合相比,使用集合推導(dǎo)式構(gòu)造集合的語法更快。


timeit("""set(i for i in range(10000))""", number=1000)

# 0.9775058150407858


timeit("""{i for i in range(10000)}""", number=1000)

# 0.5508635920123197

作為參考,您還可以在更新的版本上使用可迭代解包:


timeit("""{*range(10000)}""", number=1000)

# 0.7462548640323803

然而,有趣的是,set()直接調(diào)用時(shí)速度更快range:


timeit("""set(range(10000))""", number=1000)

# 0.3746800610097125

這恰好比集合構(gòu)造更快。您將看到其他序列(例如lists)的類似行為。


我的建議是{...}在構(gòu)造集合文字時(shí)使用集合理解,并作為將生成器理解傳遞給的替代方法set();而是用于set()將現(xiàn)有序列/可迭代對象轉(zhuǎn)換為集合。


查看完整回答
反對 回復(fù) 2021-09-28
  • 1 回答
  • 0 關(guān)注
  • 241 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號