2021年11月9日 星期二

Python 學習筆記 : 元組, 串列, 字典, 與集合的運算速度比較

今天在翻閱董付國寫的 "Python 也可以這樣學 (博碩, 2017)" 時看到一個比較串列, 字典, 與集合運算效能的範例程式, 結果顯示字典的運算速度最快, 其次是略慢一點的集合, 最差的是串列, 慢了 800 倍左右. 我另外添加了元組, 用我的 Acer  Swift 5 筆電複製此實驗, 發現結果並沒有這麼誇張 (但也許是電腦效能不同所致), 程式碼如下 : 

#test.py
import time
import random

tuple1=tuple(range(10000))
list1=list(range(10000))
set1=set(range(10000))
dict1=dict(zip(range(10000), range(10000)))
r=random.randint(0, 9999)

# test tuple
start=time.time()
for i in range(9999999):
    r in tuple1
print("elapsed time for list :", time.time()-start)
# test list
start=time.time()
for i in range(9999999):
    r in list1
print("elapsed time for list :", time.time()-start)
# test set
start=time.time()
for i in range(9999999):
    r in set1
print("elapsed time for set :", time.time()-start)
# test dict
start=time.time()
for i in range(9999999):
    r in dict1
print("elapsed time for dict :", time.time()-start)

此程式定義了 tuple1, list1, set1, 與 dict1 四的變數, 分別用 tuple(), list(), set(), 與 dict() 傳入 range(10000) 建立含有 10000 個元素的元組, 串列, 集合, 以及字典, 其中字典使用了 zip() 函式來產生成雙的元組, dict() 會將這些元組轉成鍵值對, 關於 zip() 函數參考 :


另外要注意的是, 與 range() 不同的是, random.randint(a, b) 函式傳回的是包含端點在內的隨機數, 故 random.randint(0, 9999) 有包含 9999, 但 range(9999) 則不含 9999. 

執行結果如下 : 

>>> %Run test.py
elapsed time for list : 229.00712823867798
elapsed time for list : 238.40146827697754
elapsed time for set : 0.9653775691986084
elapsed time for dict : 1.1030895709991455
>>> %Run test.py
elapsed time for list : 32.39639091491699
elapsed time for list : 32.14133930206299
elapsed time for set : 1.1040422916412354
elapsed time for dict : 0.9992852210998535
>>> %Run test.py
elapsed time for list : 423.8340582847595
elapsed time for list : 405.6691303253174
elapsed time for set : 0.8447408676147461
elapsed time for dict : 0.8417086601257324

可見集合與字典費時約 1 秒相差不大, 但元組與串列就很慢, 程度有時是集合與字典的數十倍, 有時是數百倍. 

參考 : 


沒有留言 :