目錄
- 陣列和連結串列
- 連結串列
- 對比
- 總結
1、陣列和連結串列
陣列:
陣列會在記憶體中開闢一塊連續的空間儲存資料,這種儲存方式有利也有弊端。當獲取資料的時候,直接通過下標值就可以獲取到對應的元素,時間複雜度為O(1)
。但是如果新增或者刪除資料會移動大量的資料,時間複雜度為O(n)
。陣列的擴容機制是:
如果陣列空間不足,會先開闢一塊新的空間地址,將原來的陣列複製到新的陣列中。
連結串列:
連結串列不需要開闢連續的記憶體空間,其通過指標將所有的資料連線起來。新增或者刪除的時候只需要將指標指向的地址修改就行了,時間複雜度為O(1)
。但是查詢的時間複雜度為O(n)
。
2、連結串列
2.1、雙向連結串列
雙向連結串列是各個節點之間的邏輯關係是雙向的。
雙向連結串列中節點的組成是:prior:
指向當前節點的前置節點,data:
當前節點儲存的資料。next:
指向當前節點的後置節點。
2.2、壓縮連結串列
- 壓縮連結串列是為了節約記憶體開發的。
- ziplist是一個特別的雙向連結串列,沒有維護雙向指標prev next;反而是儲存上一個entry的長度和當前entry長度,通過長度推算出下一個元素在什麼地方。
- 犧牲讀取的效能,獲得高效的儲存空間,因為儲存指標比儲存entry長度更費記憶體,這就是典型的時間換空間。
2.3、quicklist連結串列
- 官網介紹:
A doubly linked list of ziplists
A generic doubly linked quicklist implementation
- 介紹:
quicklist是一個雙向連結串列,並且是一個ziplist的雙向連結串列,ziplist本身是一個維持資料項先後順序的列表,而且資料項儲存在一個連續的記憶體塊種。
3、對比
3.1、雙向連結串列
- 雙端連結串列便於在表的兩端進行push和pop操作,但是它的記憶體開銷比較大。
- 雙端連結串列每個節點上除了要儲存的資料之外,還要額外儲存兩個指標。
- 雙端連結串列的各個節點是單獨的記憶體塊,地址不連續,節點多了容易產生記憶體碎片。
3.2、壓縮列表
- ziplist由於是一塊連續的記憶體,所以儲存效率很高。
- ziplist不利於修改操作,每次資料變動都會引發一次記憶體的realloc。
- 當ziplist長度很長的時候,一次realloc可能會導致大批量的資料拷貝,進一步降低效能。
3.3、quicklist連結串列
- 空間效率和時間效率的折中。
- 結合了雙端連結串列和壓縮列表的優點。
4、總結
在redis 3.2
版本之前使用的是 雙向連結串列和壓縮連結串列
兩種,因為雙向連結串列佔用的記憶體要比壓縮連結串列高,所以建立連結串列時首先會建立壓縮連結串列
,在合適的時機會轉化成雙向連結串列
。redis 3.2
之後使用的是quicklist連結串列
。