1. 程式人生 > >redis系列之------簡單的動態字串(SDS)

redis系列之------簡單的動態字串(SDS)

前言

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