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數組裡面的所有東西,不論英文中文,還是圖片音頻,都是二進位數據流。

 

Tags: