天道不一定酬所有勤
但是,天道只酬勤
Hollis出品的全套Java面试宝典不来了解一下吗?

Redis 为什么要自己实现用SDS实现一个字符串

Hollis出品的全套Java面试宝典不来了解一下吗?

Redis是一种KV的存储结构,他的key是字符串类型,值也支持字符串,所以字符串是redis中最常见的一个类型了。Redis自己本身是通过C语言实现的,但是他并没有直接使用C语言中的字符数组的方式来实现字符串,而是自己实现了一个SDS,即简单动态字符串,这是为什么呢?

首先,因为字符串在Redis中使用实在是太广泛了 ,所以对他的基本要求就有两点,第一就是要支持任意字符的存储,第二就是各种操作需要高效。

接着我们看看C语言中字符串的实现方式有什么问题呢?很多人可能都忘了,我帮大家回忆一下,C语言中,字符串是通过字符数组实现的,底层呢是开辟了一块连续的空间,依次存放字符串中的每一个字符。为了表示字符串的结束,他会在字符数组的最后一个字符处记录\0

也就是说,当识别到字符数组中的\0字符的时候,就认为字符串结束了,那么这么做会带来哪些问题呢?

就是这样实现的字符串中就不能保存任意内容了,至少\0就不行,因为遇到他的时候就直接截断了,这肯定是接受不了的。

还有就是因为C中的字符串以\0作为识别字符串结束的方式,所以他的字符串长度判断、字符串追加等操作,都需要从头开始遍历,一直遍历到\0的时候再返回长度或者做追加。这就使得字符串相关的操作效率都很低。

那么,想要解决上面的两个问题要怎么办呢?那就是在用字符数组表示字符串的同时,在这个字符串中增加一个表示分配给该字符数组的总长度的alloc字段,和一个表示字符串现有长度的len字段。这样在获取长度的时候就不依赖\0了,直接返回len的值就行了。

还有呢,就是在做追加操作的时候,只需要判断新追加的部分的len加上已有的len是否大于alloc,如果超过就重新再申请新空间,如果没超过,就直接进行追加就行了。

还有很多其他操作,比如复制、比较等都可以使用类似的思想高效的操作。

赞(3)
如未加特殊说明,此网站文章均为原创,转载必须注明出处。HollisChuang's Blog » Redis 为什么要自己实现用SDS实现一个字符串
Hollis出品的全套Java面试宝典不来了解一下吗?

评论 抢沙发

HollisChuang's Blog

联系我关于我