redis系列之------簡單的動態字串(SDS)
阿新 • • 發佈:2019-10-13
前言
Redis 沒有直接使用 C 語言傳統的字串表示(以空字元結尾的字元陣列,以下簡稱 C 字串), 而是自己構建了一種名為簡單動態字串(simple dynamic string,SDS)的抽象型別, 並將 SDS 用作 Redis 的預設字串表示。
個人感覺SDS類似於Java的ArrayList,大家可以拿兩者對比一些,誰的效率更加高一點。
SDS定義
1 struct sdshdr { 2 3 // 記錄 buf 陣列中已使用位元組的數量 4 // 等於 SDS 所儲存字串的長度 5 int len; 6 7 // 記錄 buf 陣列中未使用位元組的數量 8 int free; 9 10 // 位元組陣列,用於儲存字串 11 char buf[]; 12 13 };
這裡注意一下。C語言的char是佔一個位元組的。不像Java的char佔兩個位元組。也就是隻有八位,-127 - 128。
SDS相比於C字串的優勢
1. 常數複雜度獲取字串長度
- 這個比較好理解,因為SDS裡面有一個欄位為len,可以直接獲取長度
2. 減少修改字串時帶來的記憶體重分配次數
- 因為傳統的c字串,不會自動擴容。而且其記憶體大小就等於字串長度+1,因此,每修改一次字串,都要重新分配一次記憶體,非常的耗費時間
- SDS會自動擴容,並且會進行空間預分配。比如現在有一個Hello的字串。記憶體的大小可能是Hello的兩倍,也就是 5 * 2 = 10。當再次擴容字串的時候,不一定需要再次分配記憶體了。並且可以自動擴容,假設10不夠了,加了一個字串後大小為13,那麼記憶體就會分配為 13 * 2 = 26大小的記憶體。
3. 二進位制安全,以及可以儲存空字元
- C 字串中的字元必須符合某種編碼(比如 ASCII), 並且除了字串的末尾之外, 字串裡面不能包含空字元, 否則最先被程式讀入的空字元將被誤認為是字串結尾 —— 這些限制使得 C 字串只能儲存文字資料, 而不能儲存像圖片、音訊、視訊、壓縮檔案這樣的二進位制資料。
- 因此,所有 SDS API 都會以處理二進位制的方式來處理 SDS 存放在
buf
數組裡的資料 - 也就是儲存在buf數組裡面的所有東西,不論英文中文,還是圖片音訊,都是二進位制資料流。
&n