SDS(simple dynamic string) 簡單動態字符串
SDS數據結構
struct sdshdr{
// 記錄buf數組中已使用的字節的數量
int len;
// 記錄buf數組中未使用的字節的數量
int free;
// 字節數組,用于保存字符串
char buf[];
};
SDS與C字符串的區別
C字符串總是用長度為N+1的字符數組來表示長度為N的字符串,并且字符串數組的最后一個元素總是字符'\0'。
SDS常數復雜度獲取字符串長度,而C字符串則是O(N)。
SDS杜絕緩沖區溢出。這一點通過SDS的空間分配策略決定。在SDS API需要對字符數組進行修改時,API首先檢查SDS的空間是否滿足修改的需求,如果不滿足,API會自動將SDS的空間擴展至執行修改所需的大小。
SDS是二進制安全的。而C字符串必須符合某種編碼(例如ASCII),并且除了字符末尾之外,不可以包含空字符,否則最先被程序讀到的空字符將被認為是字符串結尾。因此,這限定了C字符串只能保存文本數據,而不能保存圖片,音頻,視頻等。而SDS則適用于各種不同的處理場景,SDS的API都是以處理二進制數據的方式來處理SDS存放在buf數組中的數據,程序不會對存放在其中的數據做任何限定,過濾或者假設。數據在被寫入時候是什么樣,讀取時候就是什么樣。
SDS減少修改字符串時候帶來的內存重分配
SDS通過未使用空間解除了字符串長度和底層數組長度之間的關聯。
SDS實現了兩種空間優化策略:空間預分配,和惰性空間釋放。
1.空間預分配
??當SDS的API對一個SDS修改,并且需要對SDS進行空間擴展的時候,程序不僅會為SDS分配修改所需的空間,還會為SDS分配額外的未使用空間。
如果對SDS進行修改之后,SDS的長度將小于1MB,那么程序分配和len屬性同樣大小的未使用空間,這時SDS的len屬性的值和free屬性的值相同。
??
如果對SDS修改之后,SDS的長度將大于1MB,那么程序會分配1MB的未使用空間。
??
在擴展SDS空間之前,SDS API會首先判斷未使用空間是否足夠,如果足夠的話,API就會直接使用未使用空間,而無需執行內存重分配。
??
通過這種預分配策略,SDS將連續增長N次字符串所需的內存重分配次數從必定N次降低為最多N次。
2.惰性空間釋放
惰性空間釋放用于優化SDS的字符串縮短操作:當SDS的API需要縮短SDS保存的字符串時,程序并不立即使用內存重分配來回收縮短之后多出來的字節,而是使用free屬性將這些字節的數量記錄起來,并等待將來使用。