共计 1236 个字符,预计需要花费 4 分钟才能阅读完成。
自动写代码机器人,免费开通
这篇文章主要介绍 Redis 中 SDS 和 C 字符串的区别有哪些,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
redis 底层没有使用“C 字符串”来表示, 而是用自己构建的“SDS 抽象类型”进行默认字符串表示。
C 字符串
C 字符串储存的数据, 最后会有一个空字符结尾.
举个例子, 比如说 redis 他实际的形式就是 R E D I S \0
SDS(动态字符串)
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 字符串的区别有哪些”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注丸趣 TV 行业资讯频道!
向 AI 问一下细节