redis雖說是用C語言開發的,但是redis考慮了性能、安全性、效率性、功能等要,redis底層存儲字元串實現,自己實現了名為簡單動態字元串(Simple dynamic string)簡稱SDS的結構來存儲字元串,這個結構有int len(當前字元串長度), int free(未使用的字元串長度 ...
redis雖說是用C語言開發的,但是redis考慮了性能、安全性、效率性、功能等要,redis底層存儲字元串實現,自己實現了名為簡單動態字元串(Simple dynamic string)簡稱SDS的結構來存儲字元串,這個結構有int len(當前字元串長度), int free(未使用的字元串長度可以說是緩衝), char buf[](存儲的字元串數組)這幾個變數。
接下來我們開始分析C語言預設字元串和SDS字元串的區別以及redis為什麼要使用SDS。
1、C語言的字元串存儲並不能記錄自身字元串長度,且在記憶體中實現的方式是|r|e|d|i|s|\0 最後的'\0'表示C語言的結束符,每次調用strlen方法取字元串長度無可避免得去搜索'\0'結束的字元串從而使複雜度變成O(N),redis作為一個高性能的代名詞是無法容忍這個缺陷的,所以SDS結構的len變數就有用了直接可以知道這個變數大小是多少,從而使軟體的複雜度變成O(1)。
2、C語言的2個字元串在連接得時候容易發生記憶體溢出問題,比如現在有2個連續的C字元串 a(len=6),b(實際長度8)在記憶體中分配的地址如下:
|r|e|d|i|s|\b|m|o|n|g|o|d|b|\b|
假如我現在執行strcat(a,"666")操作如果忘記了給a分配新長度的話,記憶體就會溢出,從而影響b的值,而SDS避免了這個問題,當執行給SDS添加字元串會自動檢查當前的free長度是否夠用,如果不夠會自動分配新空間,從而避免了記憶體溢出問題,其實說到這裡其實SDS作為Redis存儲的最細節關鍵的還是這個free緩衝,因為Redis的使用場景中大部分速度要求苛刻,且經常會發生字元串增加或者減少的事情,而如果每次都調用系統類庫來分配記憶體空間,會很耗時,降低性能,而Redis考慮到了這一點,使用了free,大大減少了記憶體分配的次數,從而提高了性能。
3、C語言字元串不能用來存儲二進位文件,因為c語言字元串利用了'\0'作為字元串結尾,但是二進位文件結尾是-1,而SDS有一個len變數,就解決了這個問題,可以包含多個'\0',從而可以存儲任意二進位數據。
4、SDS也遵循了C語言字元串'\0'結尾的規則,使得SDS也可以使用一部分系統的類庫。
區別圖片