简单动态字符串
简单动态字符串,simple dynamic string,SDS,抽象类型,用作redis的默认字符串表示
在redis中,包含字符串值得键值对在底层都是由SDS实现的
SDS定义
1
2
3
4
5
6
7
8
9
10
11
12struct sdshdr {
// 记录buf数组中已使用字节的数量
// 等于SDS所保存字符串的长度
int len;
// 记录buf数组中未使用字节的数量
int free;
// 字节数组,用于保存字符串
char buf[];
}通过使用SDS而不是C字符串,Redis将获取字符串长度所需的复杂度从O(N)降低到了O(1),确保了获取字符串长度的工作不会称为Redis的性能瓶颈
与C字符串不同,SDS的空间分配策略完全杜绝了发生缓冲区溢出的可能性;当SDS API需要对SDS进行修改时,API会先检查SDS的空间是否满足修改所需的要求,如果不满足的话,API自动将SDS的空间扩展至执行修改所需的大小,然后才执行实际的修改操作
通过未使用空间,SDS实现了空间预分配和惰性空间释放两种优化策略:
- 空间预分配
- SDS将连续增长N次字符串所需的内存重分配次数从比定N次降低为最多N次
- 惰性释放
- SDS避免了缩短字符串时所需的内存重分配操作,并为将来可能有的增长操作提供了优化
- 空间预分配
通过使用二进制安全的SDS,而不是C字符串,使得Redis不仅可以保存文本数据,还可以保存任意格式的二进制数据
相比C字符串,SDS具有以下优点:
- 常数复杂度获取字符串长度
- 杜绝缓冲区溢出
- 减少修改字符串长度所需的内存重分配次数
- 二进制安全
- 兼容部分C字符串函数