简单动态字符串(SDS)与C的字符串的区分
C语言中的字符串,遇到'\0'则结尾,用长度N+1的数组维护长度为N的字符串。
而Redis的SDS是
len表示字符串的长度;
free表示空闲的,未分配的空间;
buffer数组是真正的字符串,并且以'\0'结尾。
现在我们对比一下他们的差异,这也是一个出镜率很高的面试题。
1,SDS获取字符串长度复杂度O(1),而C的字符串为O(n)。
因为SDS保存了长度在len中,但是C的字符串需要从头到位遍历字符数组。
2,SDS避免了一些C的内存溢出的问题。
在C中,某些情况下会发生内存溢出的问题。假如两个字符出s1 'hello',s2 'world' 在内存中紧挨着保存着。
如果在没有给s1申请更多内存的前提下,就为s1追加一些字符串,这时就不知情的把s2的数据修改了。
而SDS字符串拼接函数,已经做好了检查长度的问题,如果空间不够,就会先扩展空间。
3,SDS通过free的内存预分配和惰性释放,降低内存分配次数
C的字符串,每当增加长度的时候,都必须申请内存,不然可能内存溢出;
每当减少长度的时候,都要释放内存,不然可能内润泄漏。
而SDS在len+free不够的时候才扩展内存
扩展的规则是 如果len小于 1Mb,则len和free保持一致,这样buffer数组长度为2*len+1;
如果len大于等于1Mb时,free总是分配1MB,这样buffer数组长度为 len+1Mb+1byte;
当SDS字符串长度减少的时候,内存并不会立即回收,而是把内存放到free中。
这样以后再需要增加长度的时候,不需要再申请内存。
4,判断字符串结尾的方式
C的字符串以遇到'\0'作为判断到了字符串结尾,而SDS以len来判断。
这样SDS中间可以包含'\0'