redis 简单动态字符串(SDS)

1 简单字符串

redis 自己构建了一种名为简单动态字符串sds的抽象类型,并将sds用作redis的默认字符串类型。

set msg "hello"
  • 键值对的键是字符串对象,实现是保存字符串“msg”的sds
  • 键值的值是字符串对象,是保存字符串“hello”的msg

SDS的定义

struct sdshdr{
    //记录已使用的字节的数量
    int len;
    // 记录数组中未使用的字节数量
    int free;
    //字节数组,用于保存字符串
    char buf[]; 
}

2 sds与c字符串的区别

2.1 常数复杂度获取字符串长度

由于c字符串并不记录自身的长度信息,所以获取c字符串长度信息,需要进行遍历 复杂度为o(N),而sds在len属性中记录了sds长度本身,所以获取仅为o(1)

2.2 杜绝缓冲区溢出

c字符串未分配足够的空间时,数据进行修改时将会发生溢出,而sds进行修改时,将会检查 free属性的大小(代表剩余空间),不足的化将会额外申请。

2.3 减少内存重分配现象

在sds中,buf数组的长度不一定是字符数量加一,数组里面可以包含未使用的字节,而这些字节数量由sds的free属性记录,通过未使用空间sds实现了空间预分配与惰性空间释放两种优化策略。

空间预分配

空间预分配用于优化sds的字符串增长操作,当需要对sds进行空间扩展时,程序不仅仅会为sds分配修改所必须要的空间,还会为sds分配额外未使用空间。

  • 如果对sds进行修改后,sds长度(属性len)小于1MB,那么程序分配和len属性同样大小的未使用空间,这时SDS的len属性值将和free属性值相同。

  • 如果进行修改后,SDS长度大于等于1MB,那么程序会分配1MB未使用空间。

    通过空间预分配,redis可以减少连续执行字符串增长操作所需的内存重分配

惰性空间释放

惰性空间释放用于优化sds字符串缩短操作,当sds需要缩短字符串时,程序并不立即使用内存重分配来回收缩短后多出来的字节,而是使用 free 属性,将这些字节的数量记录起来。

2.4 二进制安全

c字符串中的字符必须符合某种编码(ASCII),不能保存图片,音频等这样的二进制数据在读取时必须按照格式进行读取。

SDS的API都是二进制安全的,所有SDS都会以处理二进制的方式来处理SDS存放在buf数组里的数据,程序不会对其中的数据做任何限制。

2.5 总结

sds具有以下优点:

  • 常数复杂度获取字符串长度
  • 杜绝缓冲区溢出
  • 减少修改字符串长度时所需要的内存重分配次数
  • 二进制安全
  • 兼容部分c字符串函数
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值