rwe0214
nashi5566
原本有想到要使用只有 avl 的版本去做比較,但是因為原資料執行 avl 的版本時間耗費太大,又怕只用小資料會造成變因過多,所以就沒有做出 avl 的比較,之後會再思考要用什麼方式呈現Willy Chiu
raygoah
.gitignore
需要更新,hash_avl_opt.txt
以及 phonebook_hash_alv_opt
不需上傳phonebook_orig
使用 single-linklist 的資料結構儲存,其建立和搜尋的時間複雜度皆為 O(n)
,而因為 node ( 即 struct entry
) 的數量非常大,所以在搜尋 ( findName()
) 上耗費的時間非常可觀。
另外本次作業也提到觀察 cache miss 的情形,在原始結構所採用的 node 中除了儲存用來當作 index 的 lastName 外,也一併儲存其他資料 ( e.g. firstName, email, phone … ),導致一個 node 的資料大小大過於 index 非常多,又因為 cache 一次是載入一個一個 node ,再加上 cache 大小有限,所以 cache 中有著許多搜尋時用不到的資訊且而浪費了空間,所以導致此版本的 CPU 效率不彰。
for example 的縮寫是 e.g.,不是 ex
,後者是「前」女友、「前」老闆一類的前綴詞
謝謝老師提醒,已更改!Willy Chiu
基於上述的分析,大概把問題分成兩個部份,一個是從資料儲存結構下手,一個是從 node 的大小做修改,以上分別對應到 findName()
的時間和 cache miss 的情況。
O(n)
降為 O(logn)
。首先實做出 AVL-tree 的 function 並套用進 phonebook_opt 中,但是發現了一個非常糟糕的情形,就是 append()
300,000 筆資料進 AVL-tree 非常耗時,完全超出我的想像。雖然在 findName()
的時間進步到趨近於 0,但是由於 append()
的時間過於龐大,勢必需要改良。
註:以下圖片為資料量 10,000 筆的情形,因為 300,000 筆資料建置 AVL-tree 的過程我的電腦有點不堪負荷,所以先以這個資料量做比較。
因為 300,000 個節點的 AVL-tree 建置時間過長,若我能建置多棵節點沒那麼多的 AVL-tree 時間是否會降低呢?
於是我先使用 hash 把 300,000 的資料量縮小在 524288 個 buckets 的 hash table 中,然後針對每個發生 collision 的 bucket 以 AVL-tree 的資料結構儲存它所有的 slots,因為 hash table 的 access time 為 O(1)
,所以 findName()
整體的時間複雜度仍為 O(logn)
,但是實際上 AVL-tree 的節點數量下降了,應該能有效降低 append()
的時間。
此圖片資料為完整資料量約 300,000 筆資料。
想法:使用指標縮小 entry,讓 cache 一次能載入更多個 entry ,以期減少 cache。
未縮小前:
縮小後:
小結:以上結果可以看出 cache miss 從 87% 降低至 30% 。但是,如果套用到 hash-avl 的版本也會是如此嗎?
hash table size 為 524,288
hash table size 為 1024
總結:在 hash-avl 版本中,cache miss 卻大幅度的上升,試著縮小 hash table size 也指下降了一小部份,因而研判在建 AVL-tree 的過程中的樹結構的調整產生了大量的 cache miss 情形。而且發現了一個有趣的事情,就是雖然 table size 較小的 cache miss 相較比 table size 大的 cache miss 還要低,但是實際的 cache references 卻高出了非常多。