2.2Redis中SDS(簡單動態(tài)字符串)與C字符串的區(qū)別-創(chuàng)新互聯(lián)

引言:

根據(jù)傳統(tǒng),C語言使用長度N+1的字符數(shù)組來表示長度為N的字符串,并且字符數(shù)組的最后一個元素總是空字符’\0’。
例如,圖2-3 就展示了一個值為"Redis"的C字符串。
C語言使用這種簡單的字符串表示方式,并不能滿足Redis對字符串在安全性、效率以及功能方面的要求,接下來的內(nèi)容將詳細(xì)對比C字符串和SDS之間的區(qū)別,并說明SDS比C字符串更適合用于Redis的原因。

為于田等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計(jì)制作服務(wù),及于田網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè)、于田網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會得到認(rèn)可,從而選擇與我們長期合作。這樣,我們也可以走得更遠(yuǎn)!

在這里插入圖片描述

2.2.1 Redis 可以,以常數(shù)復(fù)雜度 獲取 字符串的長度

在傳統(tǒng)的C字符串中,其本身,并不記錄字符串的長度信息,如果想獲取該字符串的長度,那么就需要對字符串進(jìn)行遍歷,對遇到的每個字符進(jìn)行計(jì)數(shù),知道遇到 0元素或者 字符’\0’,這個操作的復(fù)雜度為O(N)。

和C字符串不同的是,Redis 中 SDS 在len 屬性中記錄了SDS本身的長度,所以獲取一個SDS長度的復(fù)雜度僅為O(1)。

設(shè)置和更新SDS長度的工作,是由SDS的API 在執(zhí)行時自動完成的,所以使用SDS無需進(jìn)行任何手動修改長度工作。

通過使用SDS這種字符串結(jié)構(gòu),Redis 把 獲取一個字符串的效率,從O(N) 時間復(fù)雜度降低到O(1),即使我們對一個非常長的字符串鍵,進(jìn)行反復(fù)的執(zhí)行STRLEN 命令,也不會對系統(tǒng)性能造成任何影響,因?yàn)镾TRLEN命令的時間復(fù)雜度僅為O(1)。

2.2.2 杜絕了緩沖區(qū)溢出

傳統(tǒng)C字符串,除了獲取字符串長度以外,還會造成緩沖區(qū)溢出的問題。

例如如果 對一個已經(jīng)分配好內(nèi)存空間的C語言字符串 char *dest,如果這個時候要對該字符串進(jìn)行追加的話,那么如果在沒有追加之前沒有為dest額外分配額外的空間(這往往是粗心的程序猿所做的,但是C語言中確實(shí)是這樣的。每一次對字符串進(jìn)行新增或者修改,都要進(jìn)行一次內(nèi)存分配),一旦沒有提前進(jìn)行分配,那么就會產(chǎn)生緩沖溢出。

舉個例子,加入程序中,有2個在內(nèi)存中緊鄰的C字符串s1和s2,其中s1保存了"redis",
s2保存了 “mysql5.7”,如圖2-7所示。

在這里插入圖片描述

如果一個程序員,決定通過執(zhí)行:

strcat(s1," Java");

那么s1的內(nèi)容將會被修改為"redis JAVA"(10個字符),但是粗心的他卻忘了在執(zhí)行此函數(shù)之前,為s1分配足夠的內(nèi)存空間,那么在strcat函數(shù)執(zhí)行之后,s1的數(shù)據(jù)將會溢出到s2所在的空間中,會導(dǎo)致s2保存的內(nèi)容以外地被修改,如果2-8所示。

在這里插入圖片描述

與C字符串不同的是,SDS 的空間分配策略完全杜絕了發(fā)生緩沖區(qū)溢出的可能性:當(dāng)SDS的API需要對SDS進(jìn)行修改時,API 會先檢查SDS 的空間是否滿足修改所需的要求,如果不滿足的話,API 會自動將SDS 的空間擴(kuò)展至執(zhí)行修改所需的大小,然后才執(zhí)行實(shí)際的修改操作問題,所以使用SDS既然不需要手動修改SDS的空間大小,也不會出現(xiàn)前面所說的緩沖區(qū)溢出問題。

舉個例子,SDS的API里面也有一個用于執(zhí)行拼接操作的sdscat函數(shù),可以將一個C字符串拼接到給定SDS所保存的字符串的后面,但是在執(zhí)行拼接操作之前,sdscat會先檢查給定SDS的空間是否足夠,如果不夠的話,sdscat就會先擴(kuò)展SDS的空間,然后才執(zhí)行拼接操作。

例如,如果我們執(zhí)行:

sdscat(s," Cluster");

在這里插入圖片描述

其中SDS值s 如圖2-9 所示,那么sdscat將在執(zhí)行拼接操作之前檢查s的長度是否足夠,在發(fā)現(xiàn)s目前的空間不足以拼接" Cluster"之后,sdscat就會擴(kuò)展s的空間,然后才執(zhí)行拼接
" Cluster"的操作,拼接操作完成之后的SDS如圖2-10所示。
在這里插入圖片描述
注意:圖2-10所示的SDS,sdscat不僅對這個SDS進(jìn)行了拼接操作,它還為SDS分配了13字節(jié)的未使用空間,并且拼接之后的字符串也正好是13字節(jié)長,這種現(xiàn)象既不是bug也不是巧合,它和SDS的空間分配策略有關(guān)。

鏈接: 2.2.3 Redis中的SDS減少修改字符串時帶來的內(nèi)存重分配次數(shù)

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧

本文題目:2.2Redis中SDS(簡單動態(tài)字符串)與C字符串的區(qū)別-創(chuàng)新互聯(lián)
網(wǎng)頁網(wǎng)址:http://www.muchs.cn/article44/coiiee.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供建站公司靜態(tài)網(wǎng)站、App開發(fā)、標(biāo)簽優(yōu)化、全網(wǎng)營銷推廣品牌網(wǎng)站設(shè)計(jì)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化