简单动态字符串 sds
Redis 设计了简单动态字符串(Simple Dynamic String,SDS)的结构,用来表示
字符串。相比于 C 语言中的字符串实现,SDS 这种字符串的实现方式,会提升字符串的操
作效率,并且可以用来保存二进制数据。
为什么 Redis 不用 char*?
首先得先了解char* 字符串数组的结构特点,还有 Redis对字符串的需求是什么,所以下面我们就来具体分析一下
char* 的结构设计
char*字符数组的结构很简单,就是一块连续的内存空间,依次存放了字符串中的每一个
字符。比如,下图显示的就是字符串“redis”的char*数组结构。、

从图中可以看到,字符数组的最后一个字符是“\0”,这个字符的作用是什么呢?其实,C
语言在对字符串进行操作时,char* 指针只是指向字符数组的起始位置,而字符数组的结尾
位置就用“\0”表示,意思是指字符串的结束
c语言标准库呢就是检查字符这个字符是不是\0然后不是加一往下走,是的话结束
创建了两个字串变量 a 和 b,分别给它们赋值为“red\0is”和“redis\0”。然后,我用 strlen 函数
计算这两个字符串长度,如下所示:

当程序执行完这段代码后,输出的结果分别是 3 和 5。
也就是说,char* 字符串以“\0”表示字符串的结束,其实会给我们保存数据带来一定的负
面影响。如果我们要保存的数据中,本身就有“\0”,那么数据在“\0”处就会被截断,
而这就不符合 Redis 希望能保存任意二进制数据的需求了
操作函数复杂度
用char* 会导致复杂度增加
字符串追加函数 strcat 和上边的strlen函数都需要遍历到字符串的末尾
SDS 的设计思想
因为 Redis 是使用 C 语言开发的,所以为了保证能尽量复用 C 标准库中的字符串操作函
数,Redis 保留了使用字符数组来保存实际的数据。但是,和 C 语言仅用字符数组不同,
Redis 还专门设计了 SDS(即简单动态字符串)的数据结构
SDS 结构设计
首先,SDS 结构里包含了一个字符数组 buf[],用来保存实际数据。同时,SDS 结构里还
包含了三个元数据,分别是字符数组现有长度 len、分配给字符数组的空间长度 alloc,以
及 SDS 类型 flags。其中,Redis 给 len 和 alloc 这两个元数据定义了多种数据类型,进
而可以用来表示不同类型的 SDS

在 Redis 源码中查找过 SDS 的定义,那你可能会看到,Redis 使用 typedef
给 char* 类型定义了一个别名,这个别名就是 sds
typedef char *sds;
因为 SDS 本质还是字符数组,只是在字符数组基础上增加了额外的元数据。在
Redis 中需要用到字符数组时,就直接使用 sds 这个别名。
在创建新的字符串时,Redis 会调用 SDS 创建函数 sdsnewlen。sdsnewlen 函数
会新建 sds 类型变量(也就是 char* 类型变量),并新建 SDS 结构体,把 SDS 结构体中
的数组 buf[] 赋给 sds 类型变量。最后,sdsnewlen 函数会把要创建的字符串拷贝给 sds
变量。下面的代码就显示了 sdsnewlen 函数的这个操作逻辑,你可以看下

SDS操作效率
因为它本身的数据结构
紧凑型字符串结构的编程技巧
SDS 结构中有一个元数据 flags,表示的是 SDS 类型
事实上,SDS 一共设计了 5 种类型,分别是 sdshdr5、sdshdr8、sdshdr16、sdshdr32 和 sdshdr64
这 5种类型的主要区别就在于,它们数据结构中的字符数组现有长度 len 和分配空间长度
alloc,这两个元数据的数据类型不同。
因为 sdshdr5 这一类型 Redis 已经不再使用了,主要来了解下剩余的 4 种类
型。以 sdshdr8 为例,它的定义如下所示

我们可以看到,现有长度 len 和已分配空间 alloc 的数据类型都是 uint8_t。uint8_t 是 8
位无符号整型,会占用 1 字节的内存空间。当字符串类型是 sdshdr8 时,它能表示的字符
数组长度(包括数组最后一位\0)不会超过 256 字节(2 的 8 次方等于 256)。
而对于 sdshdr16、sdshdr32、sdshdr64 三种类型来说,它们的 len 和 alloc 数据类型分
别是 uint16_t、uint32_t、uint64_t,即它们能表示的字符数组长度,分别不超过 2 的 16
次方、32 次方和 64 次方。这两个元数据占用的内存空间在 sdshdr16、sdshdr32、
sdshdr64 类型中,则分别是 2 字节、4 字节和 8 字节。
SDS 之所以设计不同的结构头(即不同类型),是为了能灵活保存不同大小的字
符串,从而有效节省内存空间
除了设计不同类型的结构头,Redis 在编程上还使用了专门的编译优化来节省内存
空间。在刚才介绍的 sdshdr8 结构定义中,我们可以看到,在 struct 和 sdshdr8 之间使
用了__attribute__ ((__packed__)),如下所示:
struct __attribute__ ((__packed__)) sdshdr8
其实这里,__attribute__ ((__packed__))的作用就是告诉编译器,在编译
sdshdr8 结构时,不要使用字节对齐的方式,而是采用紧凑的方式分配内存。这是因为在
默认情况下,编译器会按照 8 字节对齐的方式,给变量分配内存。也就是说,即使一个变
量的大小不到 8 个字节,编译器也会给它分配 8 个字节
到这里呢需要了解一下,字节对齐是为什么?
相关文章:
简单动态字符串 sds
Redis 设计了简单动态字符串(Simple Dynamic String,SDS)的结构,用来表示 字符串。相比于 C 语言中的字符串实现,SDS 这种字符串的实现方式,会提升字符串的操 作效率,并且可以用来保存二进制数据…...
“深入剖析JVM内部原理:解密Java虚拟机的奥秘“
标题:深入剖析JVM内部原理:解密Java虚拟机的奥秘 摘要:本文将深入探讨Java虚拟机(JVM)的内部原理,包括其架构、内存管理、垃圾回收机制、即时编译器等关键组成部分。通过解密JVM的奥秘,我们将更…...
使用QT纯代码创建(查找)对话框详细步骤与代码
一、创建项目文件 打开Qt Creator->文件->新建文件或项目->选择Qt Widgets Application 为项目起名字 输入类的名字 二、 了解每个文件的作用 项目创建完毕之后就会出现以下几个文件,先来分别介绍以下这些文件的作用。 Headers->finddialog.h——很显…...
4945: 二进制转十进制
4945: 二进制转十进制 时间限制: 1.000 Sec 内存限制: 128 MB 提交: 520 解决: 335 [命题人:][下载数据: 30] 提交状态报告 题目描述 将二进制数转成十进制输出 输入 一行,一个二进制数,二进制数的位数小于32位。 输出 一个十进制的整数。…...
java后端技术汇总 + 中间件 + 架构思想
1. 华为OD机考题 答案 2023华为OD统一考试(AB卷)题库清单-带答案(持续更新) 2023年华为OD真题机考题库大全-带答案(持续更新) 2. 面试题 一手真实java面试题:2023年各大公司java面试真题汇总--…...
《机器学习系统:设计与实现》读书笔记一
最近几年一直在做算法工程的工作,对机器学习系统有所涉猎,也很感兴趣。近期发现一本开源书籍《机器学习系统:设计与实现》。去图书馆找了它的纸质版,发现内容不尽相同。在这里结合两者做一个读书笔记。本文是第一篇,主…...
C语言单链表OJ题(较难)
一、链表分割 牛客网链接 题目描述: 现有一链表的头指针 ListNode* pHead,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针。 思路:…...
工业巡检ar沉浸式互动培训体验实现更加直观、生动的流程展示
以往的工业手工巡检效率极低,错误率偏高,漏检问题严重,会因为现场人员对机械设备的早期维护、操作不会,而影响正常交付和服务,智慧工业是工业智能化和信息化的重要体现,在巡检方面自然也要同步提升…...
【Spring】核心容器——依赖自动装配
Spring容器根据bean所依赖的资源在容器中自动查找并注入bean的过程叫做自动装配自动装配的方式 1、按类型 2、按名称(耦合性较高) 3、按构造方法 自动装配特点 1、自动装配用于对引用类型进行依赖注入,不能对简单类型进行操作 2、自动装配的…...
TestNG和Junit5测试框架梳理
一、testNG 1. testNG优势 注解驱动: TestNG 使用注解来标识测试方法、测试类和配置方法,使得测试更具可读性。 并行执行: TestNG 支持多线程并行执行测试,可以加速测试套件的执行。 丰富的配置: 可以通过 XML 配置文…...
算法练习Day46|139.单词拆分
LeetCode:139.单词拆分 139. 单词拆分 - 力扣(LeetCode) 1.思路 字符串是否能被字符串列表中的元素拼接出来,显然是一个背包问题,而且需要排列。 将字典转换为HashSet,利用.contains()方法判断是否存在元素与背包中的子串相同…...
Maven工程的安装配置及搭建(集成eclipse完成案例,保姆级教学)
目录 一.下载及安装及环境配置 1.下载及安装 2.环境变量的配置 3.检测是否安装成功 4.配置Maven 1.更换本地仓库 2. 配置镜像 二.集成eclipse完成案例 1.eclipse前期配置Maven 2.创建Maven工程 一.下载及安装及环境配置 1.下载及安装 下载地址:Maven – Down…...
82 | Python可视化篇 —— Plotly数据可视化
文章目录 什么是 Plotly安装 Plotly创建散点图创建线图创建条形图创建饼图创建热力图3D图(3D Plot)直方图(Histogram)3D表面图(3D Surface Plot)箱线图(Box Plot)散点地图(Scatter Map)量级地图(Choropleth Map)在网页中嵌入 Plotly 图表总结什么是 Plotly Plotly…...
Golang 包详解以及go mod
Golang 中包的介绍和定义 包(package)是多个 Go 源码的集合,是一种高级的代码复用方案,Go 语言为我们提供了 很多内置包,如 fmt、strconv、strings、sort、errors、time、encoding/json、os、io 等。 Golang 中的包可以分为三种:1、系统内置包 2、自定义包 3、第三方包…...
中级课程-SSRF(CSRF进阶)
文章目录 成因危害挖掘 成因 危害 挖掘...
C++命名空间
目录 格式 使用 命名空间的嵌套 使用 using声明 命名空间里面包含了逻辑结构上相互关联的一组类、函数、模板等。命名空间像是一个容器,把某些在逻辑结构上相关的 “ 对象 ” 放在一起并与外界区分。特别的,命名空间里的变量名或类名可以和命名空间外…...
阿里云服务器搭建Magento电子商务网站图文教程
本文阿里云百科分享使用阿里云服务器手动搭建Magento电子商务网站全流程,Magento是一款开源电商网站框架,其丰富的模块化架构体系及拓展功能可为大中型站点提供解决方案。Magento使用PHP开发,支持版本范围从PHP 5.6到PHP 7.1,并使…...
Docker安装 Kibana
目录 前言安装Kibana步骤1:准备1. 安装docker2. 搜索可以使用的镜像。3. 也可从docker hub上搜索镜像。4. 选择合适的redis镜像。 步骤2:拉取 kibana 镜像拉取镜像查看已拉取的镜像 步骤3:创建容器创建容器方式1:快速创建容器 步骤…...
数字图像处理 --- 相机的内参与外参(CV学习笔记)
Pinhole Camera Model(针孔相机模型) 针孔相机是一种没有镜头、只有一个小光圈的简单相机。 光线穿过光圈并在相机的另一侧呈现倒立的图像。为了建模方便,我们可以把物理成像平面(image plane)上的图像移到实际场景(3D object)和焦点(focal p…...
基于新浪微博海量用户行为数据、博文数据数据分析:包括综合指数、移动指数、PC指数三个指数
基于新浪微博海量用户行为数据、博文数据数据分析:包括综合指数、移动指数、PC指数三个指数 项目介绍 微指数是基于海量用户行为数据、博文数据,采用科学计算方法统计得出的反映不同事件领域发展状况的指数产品。微指数对于收录的关键词,在指…...
AI Agent 开发的工业化道路:Harness 架构深度解析
1. 引言:从提示词工程到系统工程的范式转移在 AI Agent 迈向生产环境的过程中,开发者往往会陷入“提示词迷思”,试图通过无限堆砌 Prompt 来覆盖业务边界。然而,由于大模型本质上的概率性,纯粹的提示词工程在面对长链条…...
如何完美配置FanControl风扇控制软件:Windows风扇管理的终极指南
如何完美配置FanControl风扇控制软件:Windows风扇管理的终极指南 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_T…...
开发小店简易收支台账自动生成代码,给社区团购小微店铺,做每日营收支出,智能分类汇总对账。
一个非常接地气、适合社区小店老板娘/店主使用的完整方案:基于 Python 的「社区团购小微店铺简易收支台账自动生成系统」定位:每日记账 → 自动分类 → 汇总对账 → 台账输出一、实际应用场景描述典型场景:社区团购自提点 / 小微便利店&#…...
用Python+SciPy从零实现多相滤波器组信道化:一个完整的仿真与代码解析
用PythonSciPy从零实现多相滤波器组信道化:一个完整的仿真与代码解析 在数字信号处理领域,多相滤波器组信道化技术因其高效性和灵活性,已成为宽带信号处理的核心方法之一。想象一下,当你面对一个带宽高达数百MHz的射频信号时&…...
SketchUp选择工具全解析:从点选到反选,6种技巧提升建模效率
SketchUp选择工具全解析:从点选到反选,6种技巧提升建模效率 在三维建模的世界里,精确选择是高效创作的基石。就像雕塑家需要精准控制每一处凿刻的力度和位置,SketchUp用户也必须掌握选择工具的精髓。许多中级用户虽然能完成基础建…...
2026年浙江工业职业技术学院专任教师笔试题目回顾
一、知识点考察 1、题型:填空,选择,判断,大题(电路,求放大倍数,静态工作点电流) 2、内容:反比例放大电路,静态工作点电路 3、芯片工艺相关:高温 灰…...
[特殊字符] Meixiong Niannian画图引擎效果实测:1024×1024输出在印刷级DPI下的表现
Meixiong Niannian画图引擎效果实测:10241024输出在印刷级DPI下的表现 1. 项目概述 Meixiong Niannian画图引擎是一款专为个人GPU设计的轻量化文本生成图像系统。该系统基于Z-Image-Turbo底座,深度融合了Niannian专属Turbo LoRA微调权重,针…...
OZON运营全场景导入,Captain AI系统功能适配效果
OZON运营涵盖新品选品、新品启动、合规申报、物流规划、核算复盘等多个核心场景,每个场景都有其独特的运营痛点与需求。Captain AI系统针对各核心场景,打造了专属功能适配方案,有效解决场景痛点,提升运营效果。一、OZON运营核心场…...
Rhino 7 + Grasshopper 新手避坑指南:这5个隐藏设置不打开,效率直接减半
Rhino 7 Grasshopper 新手避坑指南:这5个隐藏设置不打开,效率直接减半 刚接触Rhino和Grasshopper的新手设计师们,往往会被默认界面中那些看似无害实则拖累效率的"隐形陷阱"困扰。当你在深夜赶项目时,是否经历过反复切…...
从VGA到8K:一文读懂HDMI协议进化史与关键版本差异(1.4/2.0/2.1对比)
从VGA到8K:HDMI协议进化史与关键版本差异全解析 2002年12月,当索尼、松下、东芝等七家电子巨头联合发布HDMI 1.0标准时,很少有人能预料到这个接口会在未来二十年彻底改变视听产业的格局。如今,从家庭影院到电竞显示器,…...
