這篇文章跟大家介紹一下Redis SDS動態字串跟C字串的差別。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有幫助。
redis底層沒有使用「C字串」來表示,而是用自己建構的「SDS抽象類型」進行預設字串表示。 【相關推薦:Redis影片教學】
#C字串儲存的資料,最後會有一個空字元結尾. 舉個例子,比如說"redis" 他實際的形式就是 'R' 'E' 'D' 'I' 'S' '\0'
SDS 是redis 建構的抽象類型,主要用於儲存redis 的預設字串表示、AOF 模組中的AOF 緩衝區、客戶端狀態輸入緩衝區。
SDS抽象型別內容有:
int len, 用來記錄字串的長度
int free, 用來記錄buf數組中未使用的位元組的數量
char buf[],位元組數組用來保存字串
SDS結構如下圖所示
#1、求長度的時候
#C字串要進行遍歷才可以知道該字串的長度複雜度O(n).
SDS只需要存取內部的len屬性即可時間複雜度O(1).
2、緩衝區溢位問題
C字串設定了一個S1為「redis」 ,但是底層有一個跟他相鄰的S2為「abc」,然後這裡如果透過函數strcat 把S1拼接S3 "ccc",然後最後結果應該是「redisccc」, 但是如果本身給S1設定記憶體不夠的話,這樣會導致把與它相鄰的S2進行修改。
SDS 這裡會先根據空間是否夠用,不夠則擴展空間到夠位置,並且會多添加len長度的free未使用的空間,比如說redis字符串的長度為5,然後還會空間預先分配同等的長度5,最後實際空間長度為free len 1 為10。
3、字串記憶體分配
c字串,當給某個字串加資料或減少資料的時候, 就會重新申請記憶體但是如果過多的申請必然會導致性能的下降,更改N次則分配N次。
SDS 內部使用兩種機制惰性空間釋放跟空間預先分配
空間預先分配:
空間預先分配:指當我們進行一次空間分配以後,我們會在原有基礎上再多分配len長度的空間
這裡SDS長度小於1M的時候是free = len,舉個例子若SDS長度為6byte 則實際的空間為6byte 6byte 1byte
大於1M的時候只會多分配1M。 free = 1M, 舉例若SDS長度為60M 則實際空間為60M 1M 1byte
惰性空間釋放
## 當我們對某個字串進行減少的時候,程式並沒有立即使用記憶體重新分配來回收縮短後的字節,而是透過free記錄起來,以供後續使用,SDS也提供了對應的API,防止惰性空間導致記憶體浪費。
4、二進位安全性
c字串最後是由空字符結尾,但是如果有些特殊的資料需要空字符,會導致資料無法保存會導致提前識別第一個空字元之前的資料。 SDS 因為SDS是根據長度來進行辨識字串的所以可以保證資料的正確。 5、相容部分C語言的函數 因為SDS也遵循C的以空字元為結尾,所以它可以使用C裡面的一些函數總結 一邊學習一邊記錄筆記, 加深記憶,加油,若有什麼問題請指出,在此謝過。 更多程式相關知識,請造訪:程式設計影片! !
以上是淺談Redis SDS跟C字串的差別的詳細內容。更多資訊請關注PHP中文網其他相關文章!