简单动态字符串
Redis并不直接使用C语言字符串,而是自己构建一套简单动态字符串(simple dynamic string ,SDS)C字符串仅仅在一些无需对字符串进行修改的地方使用,例如打印日志。SDS除了用来保存数据库里面的字符串,还被用做缓冲区,AOF缓冲区,客户端状态中的输入缓冲区,都使用了SDS。
2.1 SDS的定义
2.2 SDS与C字符串的区别
2.2.1 常数复杂度获取字符串长度
C语言字符串获取长度 需要遍历整个字符串 时间复杂度为O(n) 而SDS为O(1)
2.2.2 杜绝缓冲区溢出
因为C语言字符串并不保存字符串的长度,如果在执行strcat(char *dest,const char *src)的时候,如果没有给dest分配足够多的内存的话,很有可能就会造成缓冲区溢出。而SDS的空间分配策略杜绝了缓冲区溢出的可能性,因为SDS API会先检查空闲空间是否满足修改的需求,不满足的话,会扩容以满足空间需要。
2.2.3 减少内存重分配次数
对于C语言字符串的扩容和缩容,频繁的内存申请和空间释放,因为内存的申请涉及到比较复杂的分配算法,还需要执行一些比较耗时的系统调用
而 SDS则实现了 空间预分配 和 惰性空间释放
空间预分配
惰性空间释放
2.2.4 二进制安全
C语言字符串以\0作为结束符,只能保存文本数据,不能保存图片、视频等二进制数据,为了保证redis适用于各种业务场景,所以SDS都是二进制安全的(binary-safe) , 因为SDS使用length判断字符串是否结束,所以不存在那样的问题。