Redis 简单字符串SDS相比C字符串的优势

目录

1. 📏防止”字符串长度获取”性能瓶颈

2. 保障二进制安全 👷

3. 减少内存再分配次数

4. 兼容 C 函数

5. 常用的 SDS 操作函数


C 字符串使用 Len+1 长度的字符数组来表示实际长度为 Len 的字符串,字符数组最后以空字符 '\0' 结尾,表示字符串结束。这种结构简单,但不能满足 Redis 对字符串功能性、安全性及高效性等的要求。

1. 📏防止”字符串长度获取”性能瓶颈

对于 C 字符串,若要获取其长度,则必须要通过遍历整个字符串才可获取到的。对于超 长字符串的遍历,会成为系统的性能瓶颈。

由于 SDS 结构体中直接就存放着字符串的长度数据(int len;),所以对于获取字符串长度需要消耗的系统性能,与字符串本身长度是无关的,不会成为 Redis 的性能瓶颈。

2. 保障二进制安全 👷

C 字符串中只能包含符合某种编码格式的字符,例如 ASCII、UTF-8 等,并且除了字符串末尾外,其它位置是不能包含空字符 '\0' 的,否则该字符串就会被程序误解为提前结束。而在图片、音频、视频、压缩文件、office 文件等二进制数据中以空字符 '\0' 作为分隔符的情况是很常见的。故而在 C 字符串中是不能保存像图片、音频、视频、压缩文件、office 文件等二进制数据的。

例如下面的字符串就被认为提前结束

SDS 不是以空字符 '\0' 作为字符串结束标志的,其是通过 len 属性来判断字符串是否结束的。所以,对于程序处理 SDS 中的字符串数据,无需对数据做任何限制、过滤、假设,只需读取即可。数据写入的是什么,读到的就是什么。

3. 减少内存再分配次数

C 字符串拼接会涉及到内存再分配

例如:给 China 拼接上 Beijing

⚠️因为数组的长度是固定的,而拼接会增加数组的长度,所以 C 字符串拼接不会直接拼接到原数组,而是新分配一块连续的空间,将原字符串和拼接字符串拷贝进去(内存再分配)这个过程是比较耗时的。

SDS 采用了空间预分配策略(空间换时间)与惰性空间释放策略来避免内存再分配问题。

  1. 空间预分配策略是指,每次 SDS 进行空间扩展时,程序不但为其分配所需的空间,还会为其分配额外的未使用空间,以减少内存再分配次数。而额外分配的未使用空间大小取决于空间扩展后 SDS 的 len 属性值。            
  2. SDS 对于空间释放采用的是惰性空间释放策略。该策略是指,SDS 字符串长度如果缩短,那么多出的未使用空间将暂时不释放,而是增加到 free 中。以使后期扩展 SDS 时减少内存再分配次数。

补充:

空间预分配

  • 如果 len 属性值小于 1M,那么分配的未使用空间 free 的大小与 len 属性值相同。
  • 如果 len 属性值大于等于 1M ,那么分配的未使用空间 free 的大小固定是 1M。

如果要释放 SDS 的未使用空间,则可通过 sdsRemoveFreeSpace()函数来释放。

4. 兼容 C 函数

Redis 中提供了很多的 SDS 的 API,以方便用户对 Redis 进行二次开发。为了能够兼容 C 函数,SDS 的底层数组 buf[]中的字符串仍以空字符'\0'结尾。

例如:现在要比较的双方,一个是 SDS,一个是 C 字符串,此时可以通过 C 语言函数

strcmp(sds_str->buf,c_str),sds 中 char buf[] buf 中放的就是 C 字符串

5. 常用的 SDS 操作函数

下表列出了一些常用的 SDS 操作函数及其功能描述。(了解,主要用于对 redis 的二次开发)

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

PJP__00

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值