共計(jì) 1236 個(gè)字符,預(yù)計(jì)需要花費(fèi) 4 分鐘才能閱讀完成。
自動(dòng)寫代碼機(jī)器人,免費(fèi)開通
這篇文章主要介紹 Redis 中 SDS 和 C 字符串的區(qū)別有哪些,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!
redis 底層沒有使用“C 字符串”來表示, 而是用自己構(gòu)建的“SDS 抽象類型”進(jìn)行默認(rèn)字符串表示。
C 字符串
C 字符串儲(chǔ)存的數(shù)據(jù), 最后會(huì)有一個(gè)空字符結(jié)尾.
舉個(gè)例子, 比如說 redis 他實(shí)際的形式就是 R E D I S \0
SDS(動(dòng)態(tài)字符串)
SDS 是 redis 構(gòu)建的一種抽象類型,主要用于儲(chǔ)存 redis 的默認(rèn)字符串表示、AOF 模塊中的 AOF 緩沖區(qū)、客戶端狀態(tài)輸入緩沖區(qū)。
SDS 抽象類型內(nèi)容有:
int len, 用來記錄字符串的長(zhǎng)度
int free, 用來記錄 buf 數(shù)組中未使用的字節(jié)的數(shù)量
char buf[], 字節(jié)數(shù)組用來保存字符串
SDS 結(jié)構(gòu)如下圖所示
區(qū)別
1、在求長(zhǎng)度的時(shí)候
C 字符串要進(jìn)行遍歷才可以知道該字符串的長(zhǎng)度 復(fù)雜度 O(n).
SDS 只需要訪問內(nèi)部的 len 屬性即可 時(shí)間復(fù)雜度 O(1).
2、緩沖區(qū)溢出問題
C 字符串 設(shè)置了一個(gè) S1 為“redis”, 但是底層有一個(gè)跟他相鄰的 S2 為“abc”, 然后這里如果通過函數(shù) strcat 把 S1 拼接 S3 ccc , 然后最后結(jié)果應(yīng)該是“redisccc”, 但是如果本身給 S1 設(shè)置內(nèi)存不夠的話, 這樣會(huì)導(dǎo)致把與它相鄰的 S2 進(jìn)行修改。
SDS 這里會(huì)先根據(jù)空間是否夠用, 不夠則擴(kuò)展空間到夠位置, 并且會(huì)多添加 len 長(zhǎng)度的 free 未使用的空間, 比如說 redis 字符串的長(zhǎng)度為 5, 然后還會(huì)空間預(yù)分配同等的長(zhǎng)度 5, 最后實(shí)際空間長(zhǎng)度為 free + len + 1 為 10。
3、字符串內(nèi)存分配
c 字符串, 當(dāng)給某個(gè)字符串加數(shù)據(jù)或減少數(shù)據(jù)的時(shí)候, 就會(huì)重新申請(qǐng)內(nèi)存 但是如果過多的申請(qǐng)必然會(huì)導(dǎo)致性能的下降,更改 N 次則分配 N 次。
SDS 內(nèi)部使用兩種機(jī)制 惰性空間釋放跟空間預(yù)分配
空間預(yù)分配:
空間預(yù)分配:指當(dāng)我們進(jìn)行一次空間分配以后, 我們會(huì)在原有基礎(chǔ)上再多分配 len 長(zhǎng)度的空間
這里 SDS 長(zhǎng)度小于 1M 的時(shí)候是 free = len, 舉個(gè)例子若 SDS 長(zhǎng)度為 6byte 則實(shí)際的空間為 6byte + 6byte + 1byte
大于 1M 的時(shí)候只會(huì)多分配 1M。free = 1M, 舉個(gè)例子若 SDS 長(zhǎng)度為 60M 則實(shí)際空間為 60M + 1M + 1byte
惰性空間釋放
當(dāng)我們對(duì)某個(gè)字符串進(jìn)行減少的時(shí)候,程序并不立即使用內(nèi)存重新分配來回收縮短后的字節(jié),而是通過 free 記錄起來,以供后續(xù)使用,SDS 也提供了相應(yīng)的 API,防止惰性空間導(dǎo)致內(nèi)存浪費(fèi)。
4、二進(jìn)制安全
c 字符串最后是由空字符結(jié)尾, 但是如果有些特殊的數(shù)據(jù)需要空字符,會(huì)導(dǎo)致數(shù)據(jù)無法保存會(huì)導(dǎo)致提前識(shí)別第一個(gè)空字符之前的數(shù)據(jù)。SDS 因?yàn)?SDS 是根據(jù)長(zhǎng)度來進(jìn)行識(shí)別字符串的所以可以保證數(shù)據(jù)的正確。
5、兼容部分 C 語言的函數(shù)
因?yàn)?SDS 也遵循 C 的以空字符為結(jié)尾, 所以它可以使用 C 里面的一些函數(shù)
總結(jié)
以上是“Redis 中 SDS 和 C 字符串的區(qū)別有哪些”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注丸趣 TV 行業(yè)資訊頻道!
向 AI 問一下細(xì)節(jié)