第一部分之简单字符串SDS(第二章)
一,什么是SDS?
1.引出SDS
C字符串:c语言中,用空字符结尾的字符数组表示字符串
简单动态字符串(SDS):Redis中,用SDS来表示字符串。在Redis中,包含字符串值的键值对在底层都是由SDS实现的
首先,Redis使用C语言写的,但是Redis没有使用C语言传统的字符串表示,它自己构建了简单字符串的抽象类型来表示字符串。
2.SDS的定义
一个sdshdr结构表示一个SDS值。结构如下:
struct sdshdr {
//记录buf数组中已使用字节的数量
int len;
//记录buf数组中未使用字节的数量
int free;
//char类型的数组,用来保存字符串
char buf[];
}
注意:SDS还是遵循了C字符串以空字符结尾的惯例,最后一个字节保存空字符'\0'。这样做的好处是SDS可以重用一些C字符串函数库里面的函数。
3.SDS和C字符串的区别
A.结构上
B.获取字符串的长度时:
C字符串需要遍历整个字符串,当发现空字符时,停止计数。时间复杂度为O(n)。
SDS中的len属性记录了SDS的长度。时间复杂度为O(1)。
C.杜绝缓冲区溢出:
由于C字符串不记录自身的长度。当修改字符串之前,如果没有为字符串分配(我们手动分配)足够的空间,会造成缓冲区溢出
当修改SDS字符串时,API会先检查SDS的空间是否满足修改所需要的要求(通过 len free 来判断)。如果不满足,API会自动(不需要我们手动分配)修改SDS空间的大小
D.减少内存重新分配次数
对于C字符串来说,每次修改时,都需要对保存这个C字符串的数组进行一次内存重新分配操作。
如果拼接字符串,在拼接之前,程序需要先通过内存重新分配扩展底层数组的空间大小。否则会缓冲区溢出
如果缩短字符串,在截断字符串之后,程序需要通过内存重新分配来释放不用的空间。否则会内存泄漏
对于SDS来说,通过未使用空间 len free,实现了空间预分配和惰性空间释放两种优化策略。
空间预分配(字符串增长):修改之后,如果SDS的长度小于1MB,程序分配和len同样大小的未使用(len free)
空间。如果大于1MB的空间,程序分配1MB的未使用空间。
惰性空间释放(字符串缩短):缩短字符串后,程序不是立即使用内存重新分配来回收缩短后多出来的字节,
而是使用free属性将这些字节的数量记录起来,等待将来使用。
E.二进制安全
只关心二进制化的字符串,不关心具体格式,只会严格按照二进制的数据存取,不会根据某种特殊的标志来解析。
C字符串中,空字符串被当做字符串的结尾来解析的。比如存hello world字符串时,C字符串只会保存hello。因为对于中间的空格,C字符串解析成空字符,当做这个字符串的结尾。world就丢失了。但是SDS字符串,写入是什么样,它被读取就是什么样。那么SDS是如何判断字符串是否结束呢?通过len属性的值获取字符串的长度,字符串长度是多少,在读取字符串的时候就读取多少长度。
F.兼容部分C字符串函数
通过遵循C字符串以空字符结尾的惯例,SDS可以在有需要的时候重用<String.h>函数库
第一部分之简单字符串SDS(第二章)的更多相关文章
- IE6/7/8中parseInt第一个参数为非法八进制字符串且第二个参数不传时返回值为0
JavaScript中数字有十进制.八进制.十六进制.以"0"开头的是八进制,"0x"或"0X"开头的是十六进制. parseInt用来把字 ...
- perl5 第二章 简单变量
第二章 简单变量 by flamephoenix 一.整型 二.浮点数 三.字符串 基本上,简单变量就是一个数据单元,这个单元可以是数字或字符串.一.整型 1.整型 PERL最常用的简单变量,由 ...
- 【C语言探索之旅】 第一部分第四课第二章:变量的世界之变量声明
内容简介 1.课程大纲 2.第一部分第四课第二章:变量的世界之变量声明 3.第一部分第四课第三章预告:变量的世界之显示变量内容 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布 ...
- Python3-Cookbook总结 - 第二章:字符串和文本
第二章:字符串和文本 几乎所有有用的程序都会涉及到某些文本处理,不管是解析数据还是产生输出. 这一章将重点关注文本的操作处理,比如提取字符串,搜索,替换以及解析等. 大部分的问题都能简单的调用字符串的 ...
- Unity 游戏框架搭建 2019 (九~十二) 第一章小结&第二章简介&第八个示例
第一章小结 为了强化教程的重点,会在合适的时候进行总结与快速复习. 第二章 简介 在第一章我们做了知识库的准备,从而让我们更高效地收集示例. 在第二章,我们就用准备好的导出工具试着收集几个示例,这些示 ...
- 《Entity Framework 6 Recipes》翻译系列 (3) -----第二章 实体数据建模基础之创建一个简单的模型
第二章 实体数据建模基础 很有可能,你才开始探索实体框架,你可能会问“我们怎么开始?”,如果你真是这样的话,那么本章就是一个很好的开始.如果不是,你已经建模,并在实体分裂和继承方面感觉良好,那么你可以 ...
- 《LINUX内核设计与实现》读书笔记之第一章和第二章
一.第一章 1. Unix内核的特点简洁:仅提供系统调用并有一个非常明确的设计目的抽象:几乎所有东西都被当做文件可移植性:使用C语言编写,使得其在各种硬件体系架构面前都具备令人惊异的移植能力进程:创建 ...
- C#本质论读书笔记:第一章 C#概述|第二章 数据类型
第一章 1.字符串是不可变的:所有string类型的数据,都不可变,也可以说是不可修改的,不能修改变量最初引用的数据,只能对其重新赋值,让其指向内存中的一个新位置. 第二章 2.1 预定义类型或基本类 ...
- Spring 3.x 实践 第一个例子(Spring 3.x 企业应用开发实战读书笔记第二章)
前言:工作之后一直在搞android,现在需要更多和后台的人员交涉,技术栈不一样,难免鸡同鸭讲,所以稍稍学习下. 这个例子取自于<Spring 3.x 企业应用开发实战>一书中的第二章,I ...
随机推荐
- [Hive_add_10] Hive 的 serde (序列化 & 反序列化) 操作
0. 说明 serde 是序列化和反序列化 serialize & deserialize 是将文件中的字段映射成 Hive 中的列 1. 验证 1.1 openCSVSerde CSV 为逗 ...
- ASP.NET -- WebForm -- .aspx与.aspx.cs文件
ASP.NET -- WebForm -- .aspx与.aspx.cs文件 1. ASP.NET -- WebForm(C#)文件 .aspx文件:是Html页面,页面的布局,样式在该文件中设计. ...
- 使用epoll实现聊天室功能,同时比较epoll和select的异同
1.首先介绍一下select和epoll的异同,如下(摘抄自https://www.cnblogs.com/Anker/p/3265058.html) select的几大缺点: (1)每次调用sele ...
- BIZHUB184打印机提示维修召唤(m2)修复
其他不用管,按照操作直接干:菜单键--常用设置--左键---左键---常用设置--左键---右键 咦 神奇的进入了service mode 服务模式 选择CLEAR DATA 项---- ...
- C# 隐藏最大化、最小化和关闭三个按钮
在Windows的窗体编程中,基本上每一个窗体都是一个最小化.最大化和关闭按钮的. 一.禁用最大化和最小化 对于最大化和最小化按钮,在C#窗体开发时,各一个属性来启用或禁用这两个按钮. this.Ma ...
- Teradata 批量查找PI字段
select * from dbc.indicesv where indextype in ('P','Q');
- 【BZOJ3451】Normal
[BZOJ3451]Normal Description 某天WJMZBMR学习了一个神奇的算法:树的点分治! 这个算法的核心是这样的: 消耗时间=0 Solve(树 a) 消耗时间 += a 的 大 ...
- w3m 在ubuntu中的使用
w3m 使用总结 安装 sudo apt install w3m终端 w3m www.baidu.com 即可打开w3m是个开放源代码的命令行下面的网页浏览器.一般的linux系统都会自带这个工具,可 ...
- 前端导出excel表
前端导出excel表 方式一: 前端js实现 : https://www.cnblogs.com/zhangym118/p/6235801.html 方式二: java后端实现: https://bl ...
- 【转】理解WebKit和Chromium: JavaScript引擎简介
转载请注明原文地址:http://blog.csdn.net/milado_nju1. 什么是JavaScript引擎什么是JavaScript引擎?简单来讲,就是能够提供执行JavaScript代码 ...