Redis string类型底层使用SDS(Simple Dynamic String)表示,而不是使用C字符串。
SDS 结构定义:
struct sdshdr {
// 记录buf数组已使用的字节数量等于SDS所保存的字符串长度
int len;
// 记录buf数组中未使用的字节数量
int free;
// 字节数组,用于保存字符串
char buf[];
}
为什么使用SDS,而不是使用C字符串呢?使用SDS有什么优势呢?
原因当然是提高性能啦。。。
优势:
1. 获取字符串长度的时间复杂度为O(1)
由于C字符串未保存字符长度,所以获取字符串长度需要遍历整个字符串,直到遇到字符串结束标志'\0',其时间复杂度为O(N)。而SDS保存了字符串长度,所以时间复杂度为O(1)。
2. 杜绝缓冲区溢出
由于SDS保存了缓冲区未使用的字节数量。在向缓冲区加入新的数据时,首先判断剩余缓冲区的长度,如果不够,会重新分配缓冲区。不会出现像C字符串缓冲区溢出的现象。
3.减少修改字符串时带来的内存重分配次数
由于C字符串在内存中保存的总是字符串长度加1的字符空间,每次修改字符串,都会发生内存重新分配,修改N次则内存重新分配N次。而SDS会预留一部分空间,来预防字符串修改,从而做到了修改N次内存最多重新分配N次。
4. 二进制安全
C字符串遇到空格会被截断,而SDS会根据len成员变量来得到实际的字符串。即使中间有空格也不会截断。例如 "Redis Cluser" 这个字符串,大家可以想象一下C字符串和SDS的区别。
这些大概就是Redis为什么要使用SDS的原因和优势了,本人水平有限,如有不对的地方,还请大家不吝赐教。