Tip:
Highlight text to annotate it
X
在論壇上關於 hash table
我們有很多很棒的問題
一個例子是學生 Baracha 提問:
"Python 如何決定當字典成長變大時,
要有多少'桶' (bucket) 呢?"
這是一個重要的問題
關於 hash table,還有很多、很多有趣的事情
但在第五單元我們沒有談到
如果記憶體是免費、廉價、而且同樣地快速
無論你需要多少
你寧願 hash table 愈大愈好,對嗎?
你會想要你的 hash table 裡有數十億個'桶"
然後在每個'桶'內,就不必儲存一個以上的項目
但正如我們在第三單元所見,記憶體可能很昂貴
速度愈快而且愈接近處理器的記憶體
它的費用也愈昂貴
所以你的記憶體數量非常有限
這是儘量保持 hash table 小的原因
這是一個艱難的權衡
好的 hash table 實作
嘗試為你做了權衡
讓你在性能和記憶體使用上,得到適當的平衡
他們根據負載因數 (load factor) 來做權衡
我們確實在第四單元使用它
也就是'項目的數量'除以'桶數'
我們在第五單元有一個問題, "N 除以 B"
在問題中,你看到'桶數'和'項目的數量'變化所產生的影響
當你做這件事時,你必須擔心一件事
如果你只看著'關鍵字數目'和'桶數'
這是平均的大小,但在許多應用中的問題
更重要的是'最壞的大小' (worse size), 即使平均大小是相當小的
'最壞的大小' (worse size) 可能會比這個大得多
如果對於最壞情況 (worse case) 的項目 做查找 (lookup) 開始變得很糟
然後你會想要更多的'桶'
或是以某種方式來改變你的 hash 函式
所以,對於一個典型的 hash table 實作
通常目標是要讓負載因數 (load factor) 實際上小於 1
對於 Python 的字典實作
如果關鍵字的數量超過約 2/3
我認為它實際上剛好是表的大小的 2/3
這是表的大小重新做調整的點
表會變成兩倍大
這會改變每個字所出現的'桶'
因為我們之前看到 hash table 的結果
取決於你所擁有的'桶數'
因此必須要將資料複製到新的 hash table
新的 hash table 有更多的空間,會使得查找速度更快
也就是說,如果你在 hash table 有大約 100 萬個項目
你會期待有 150 萬個'桶'
但當你增加到 2/3 的門檻值
然後你要把'桶'的大小增為兩倍
所以你最後會有 300 萬'桶',
如果你在 2/3 的門檻值上多加一個項目
所以,如果你比較這個與我們在第五單元所做的
你可能會驚訝它的負載因數是如此之低
我們做的 hash table 範例
'桶數'非常小
每'桶'有許多項目
這部分是為了更容易看出到底是怎麼回事
因為如果你看到一個 hash table 有上千個空'桶'
那將很難列印出來
但其他的原因是
我們在第五單元實作 hash table 的方式是, 每個'桶'是一個列表
使用列表,這是一種相當昂貴的資料結構
你得建立這些空列表
才能建立你的 hash table
Python 字典的實作方式
只是一個扁平的列表
這意謂著每個 hash 值只有一個空間
如果 hash 到一個特定的'桶'
只存在一個空間
也就是說,如果兩個物件 hash 到相同的'桶'
你必須去做點別的事情
Python 字典實作如何處理呢
你需要另一個多餘的地方來放置它
你有方法來決定當第一個'桶'滿了時
到那裡尋找下一個
這使得查找和添加項目到表中,變得更為複雜
這就是為什麼我們沒有這樣做的原因
但這也意謂著,使用較少的記憶體
因為你不必為這些'空桶'
存放這些空列表
"Beautiful Code" 這本書中有一章很棒
談的是所有關於 Python 字典的實作
所以,如果你對實際的實作感到興趣
我鼓勵你看看這一章