Redis的String物件
Redis沒有直接使用C語言傳統的字串表示(以空字元結尾的字元陣列,以下簡稱C字串),而是自己構建了一種名為簡單動態字串(simple dynamic string,SDS)的抽象型別,並將SDS用作Redis的預設字串表示。
在Redis裡面,C字串只會作為字串字面量用在無需對字串值進行修改的地方,比如列印日誌。
SDS的定義
struct sdshdr{
int len;//記錄buf陣列中使用位元組的數量,但不包括空字元
int free;//記錄buf陣列中未使用位元組的數量;
char buf[];//字元陣列
}
如圖:
SDS與C字串的區別(重點)
- 常數複雜度獲取字串長度
C字串本身不記錄自身的長度資訊,當需要獲取本身的長度時就不需迴圈,對遇到的字元進行記數,直到遇到代表字串結尾的空字元為止,這個操作的時間複雜度為O(N);而SDS本身記錄的自身的長度len,故可以以O(1)的時間複雜度獲取字串長度 - 杜絕緩衝區溢位
C字串不記錄自身的長度,所以strcat假定使用者在執行這個函式時,已經為dest(目標字串)分配了足夠多的記憶體,可以容納src(源字串)字串的所有內容,而一旦這個假定不成立時,就會產生緩衝區溢位。
與C字串不同,SDS的空間分配策略杜絕了發生緩衝區溢位的可能性;當SDSAPI需要對SDS進行修改時,API會先檢查SDS的空間是否滿足修改所需的要求;如果不滿足的話,API會自動將SDS的空間擴充套件至執行修改所需的大小(當出現上圖情況,SDS會怎麼處理?),然後才執行實際的修改操作,所以使用SDS既不需要手動修改SDS的空間大小(C語言中需要自己分配空間,修改字元陣列的空間大小),也不會出現前面所說的緩衝區溢位問題。
減少修改字串時帶來的記憶體重分配次數
兩個策略:(1)空間預分配;(2)惰性空間釋放
為什麼SDS會減少修改字串時帶來的記憶體重分配次數,其實是跟它的分配策略是相關的。
當進行拼接操作時,SDS會擴充空間,擴充多少空間呢?會擴充至拼接後len*2+1(1是空字元所佔用的位元組),比如原來有8個字元,1個空字元(即,len為8),但free是0,此時需要拼接“hello”,明顯空間不足,SDS將會分配空間,最終len等於13,free等於13,總共的空間為len+free+1。SDS不像C一樣,每次擴充至剛剛好夠用的空間,它會預留一些空間讓下次可能會進行的再拼接使用,所以因為這個策略,SDS就減少了修改字串帶來的記憶體重分配次數。即,C語言修改字元N次,它必須進行記憶體重分配N次;SDS修改字元N次,它最多進行記憶體重分配N次。(這種策略叫“空間預分配
”)
以上所講都是拼接strcat的情況,那如果進行釋放trim的情況呢?
當SDS的API需要縮短SDS儲存的字串時,程式並不立即使用記憶體重分配來回收縮短後多出來的位元組,而是使用free屬性將這些位元組的數量記錄起來,並等待將來使用。(這種策略叫“惰性空間釋放”)
二進位制安全
C字串裡面不能包含空字元,否則最先被吃呢工序讀入的空字元將誤認為是字串結尾,這些限制使得C字串只能儲存文字資料,而不能儲存像圖片、音訊、視訊、壓縮檔案這樣的二進位制資料。
SDS的API都是二進位制安全的,所有SDS API都會以二進位制的方式來處理SDS存放在buf陣列李的資料,程式不會對其中的資料做任何限制、過濾或者假設,資料在寫入時是什麼樣的,它讀取時就是什麼樣。
這也是我們將SDS的buf屬性稱為位元組陣列的原因——Redis不是用這個陣列來儲存字元,而是用它來儲存一系列二進位制資料。
相關文章
- Redis 儲存物件資訊是用 Hash 還是 StringRedis物件
- String物件的equals()與 = =物件
- Redis之StringRedis
- Redis的字串型別(String)Redis字串型別
- Javascript String物件方法JavaScript物件
- JavaScript 基礎(二) – 建立 function 物件的方法, String物件, Array物件JavaScriptFunction物件
- Redis命令String(字串)教程Redis字串
- 2、Redis的資料型別-stringRedis資料型別
- 常見物件-String類物件
- 關於建立String物件的抉擇物件
- Array String物件的方法和屬性物件
- redis-6.string型別Redis型別
- String s = new String(" a ") 到底產生幾個物件?物件
- String s=new String("abc")建立了幾個物件?物件
- Redis的字串物件筆記Redis字串物件筆記
- JavaScript 複習之 String 物件JavaScript物件
- 建立了幾個String物件?物件
- 常見物件-String類-2物件
- 常見物件-String類-3物件
- 常見物件-String類-4物件
- 支援正規表示式的 String 物件的方法物件
- Redis in .NET Core 入門:(2) StringRedis
- redis string 簡單動態字串Redis字串
- Redis之string型別及操作Redis型別
- 蜻蜓點水說說Redis的String的奧祕Redis
- Redis有序集合物件Redis物件
- Redis - 物件結構Redis物件
- Redis 物件系統Redis物件
- Redis物件系統Redis物件
- Java String 物件,你瞭解多少?Java物件
- JavaScript String 物件擴充套件方法JavaScript物件套件
- Java String 對 null 物件的容錯處理JavaNull物件
- Redis OM .NET Redis物件對映框架Redis物件框架
- JAVA面試題 String s = new String("xyz");產生了幾個物件?Java面試題物件
- redis原始碼分析(三)redis命令學習總結—string字串Redis原始碼字串
- Redis物件——有序集合(ZSet)Redis物件
- C++:String物件的構造及深拷貝C++物件
- ava String 物件,你真的瞭解了嗎?物件