重庆分公司,新征程启航

为企业提供网站建设、域名注册、服务器等服务

2.2Redis中SDS(简单动态字符串)与C字符串的区别-创新互联

引言:

根据传统,C语言使用长度N+1的字符数组来表示长度为N的字符串,并且字符数组的最后一个元素总是空字符’\0’。
例如,图2-3 就展示了一个值为"Redis"的C字符串。
C语言使用这种简单的字符串表示方式,并不能满足Redis对字符串在安全性、效率以及功能方面的要求,接下来的内容将详细对比C字符串和SDS之间的区别,并说明SDS比C字符串更适合用于Redis的原因。

为于田等地区用户提供了全套网页设计制作服务,及于田网站建设行业解决方案。主营业务为网站设计、网站建设、于田网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!

在这里插入图片描述

2.2.1 Redis 可以,以常数复杂度 获取 字符串的长度

在传统的C字符串中,其本身,并不记录字符串的长度信息,如果想获取该字符串的长度,那么就需要对字符串进行遍历,对遇到的每个字符进行计数,知道遇到 0元素或者 字符’\0’,这个操作的复杂度为O(N)。

和C字符串不同的是,Redis 中 SDS 在len 属性中记录了SDS本身的长度,所以获取一个SDS长度的复杂度仅为O(1)。

设置和更新SDS长度的工作,是由SDS的API 在执行时自动完成的,所以使用SDS无需进行任何手动修改长度工作。

通过使用SDS这种字符串结构,Redis 把 获取一个字符串的效率,从O(N) 时间复杂度降低到O(1),即使我们对一个非常长的字符串键,进行反复的执行STRLEN 命令,也不会对系统性能造成任何影响,因为STRLEN命令的时间复杂度仅为O(1)。

2.2.2 杜绝了缓冲区溢出

传统C字符串,除了获取字符串长度以外,还会造成缓冲区溢出的问题。

例如如果 对一个已经分配好内存空间的C语言字符串 char *dest,如果这个时候要对该字符串进行追加的话,那么如果在没有追加之前没有为dest额外分配额外的空间(这往往是粗心的程序猿所做的,但是C语言中确实是这样的。每一次对字符串进行新增或者修改,都要进行一次内存分配),一旦没有提前进行分配,那么就会产生缓冲溢出。

举个例子,加入程序中,有2个在内存中紧邻的C字符串s1和s2,其中s1保存了"redis",
s2保存了 “mysql5.7”,如图2-7所示。

在这里插入图片描述

如果一个程序员,决定通过执行:

strcat(s1," Java");

那么s1的内容将会被修改为"redis JAVA"(10个字符),但是粗心的他却忘了在执行此函数之前,为s1分配足够的内存空间,那么在strcat函数执行之后,s1的数据将会溢出到s2所在的空间中,会导致s2保存的内容以外地被修改,如果2-8所示。

在这里插入图片描述

与C字符串不同的是,SDS 的空间分配策略完全杜绝了发生缓冲区溢出的可能性:当SDS的API需要对SDS进行修改时,API 会先检查SDS 的空间是否满足修改所需的要求,如果不满足的话,API 会自动将SDS 的空间扩展至执行修改所需的大小,然后才执行实际的修改操作问题,所以使用SDS既然不需要手动修改SDS的空间大小,也不会出现前面所说的缓冲区溢出问题。

举个例子,SDS的API里面也有一个用于执行拼接操作的sdscat函数,可以将一个C字符串拼接到给定SDS所保存的字符串的后面,但是在执行拼接操作之前,sdscat会先检查给定SDS的空间是否足够,如果不够的话,sdscat就会先扩展SDS的空间,然后才执行拼接操作。

例如,如果我们执行:

sdscat(s," Cluster");

在这里插入图片描述

其中SDS值s 如图2-9 所示,那么sdscat将在执行拼接操作之前检查s的长度是否足够,在发现s目前的空间不足以拼接" Cluster"之后,sdscat就会扩展s的空间,然后才执行拼接
" Cluster"的操作,拼接操作完成之后的SDS如图2-10所示。
在这里插入图片描述
注意:图2-10所示的SDS,sdscat不仅对这个SDS进行了拼接操作,它还为SDS分配了13字节的未使用空间,并且拼接之后的字符串也正好是13字节长,这种现象既不是bug也不是巧合,它和SDS的空间分配策略有关。

链接: 2.2.3 Redis中的SDS减少修改字符串时带来的内存重分配次数

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


分享题目:2.2Redis中SDS(简单动态字符串)与C字符串的区别-创新互联
分享URL:http://cqcxhl.cn/article/coiiee.html

其他资讯

在线咨询
服务热线
服务热线:028-86922220
TOP