Sds比c字符串的优点
1) 常数复杂度获取字符串长度。
C字符串不记录自身长度信息,获取c字符串长度的操作,是采用遍历操作整个字符串,对每个字符进行计数,直到结尾的空字符为止;SDS在len属性中记录了SDS本身的长度,读取len属性即可获得字符的长度
2) 杜绝缓冲区溢出
因为c字符串不记录自身长度,所以用户在执行字符串拼接操作(srccat),如果目标字符串内存空间不足,而紧邻的空间又有内容保存,那么紧邻的空间的内容将被占用,原来保存的内容被覆盖,产生缓冲区溢出。SDS空间分配策略完全杜绝了发生缓冲区溢出的可能性:当需要对sds进行修改是,首先先检查sds空间是否满足修改所需的要求,如果空间不足,先自动对SDS进行空间扩展,然后再执行修改操作。
3) 减少修改字符串长度时所需的内存重分配次数
因为C字符串不记录自身长度,C字符串数据的最后一位用于保存空字符作为终结,而对C字符串进行拼接或者删减,都要对内存空间进行重分配扩展数组空间或释放空间,如果不进行空间重分配,前者会造成缓冲区溢出,后者会产生内存泄漏。
SDS数组长度不一定是字符串数量加一,SDS实现了空间预分配和惰性空间释放两种优化策略进行空间的管理。
a) 空间预分配,当SDS进行空间扩展时,不仅会分配修改所需空间,还会分配额外的未使用空间(如果修改之后的空间小于1MB,修改后的实际长度为修改后的长度*2+1,额外的1字节用于保存空字符串;如果修改之后的长度大于等于1MB,会在再多分配1MB的未使用空间,实际长度修改后的长度+1MB+1byte)
b) 惰性空间释放,SDS字符串进行缩短操作,程序并不立即使用空间重分配来缩短多出来的字节,而是用free属性记录下来,以备下次使用
4) 二进制安全
C字符串的字符必须符合某种编码格式,并且字符串里不能包含空字符串,这就决定了C字符串只能保存文本数据,而不能保存图片、音频、视频和压缩文件这样的二进制数据
5) 兼容部分c字符串函数
Redis就不用自己专门写一个函数对比SDS和C字符串值