Redis 底层对 String 的 3 个优化
Redis对 String 类型实现了很多优化,通过以下三个重要的优化点来解释:
1. 简单动态字符串(SDS)
Redis 的 String 类型内部采用简单动态字符串(SDS)来管理字符串。相比于 C 语言的原生字符串,SDS 有以下优势:
- 能够动态地改变自己的长度,避免了不必要的内存分配和拷贝操作;
- SDS 本身有一个长度属性,可以快速计算字符串的长度;
- SDS 可以与 C 语言原生字符串互相转换,方便对 C 语言中一些函数的使用。
SDS 源码:
struct sdshdr {int len; // 字符串实际长度int free; // 字符串剩余空间char buf[]; // 字符串数据
};
源码解释:redis 源码实现 sds 函数,定义了 SDS 的各种操作函数,例如 sdsnew() 函数用于新建 SDS 字符串,sdsempty() 函数用于初始化一个空 SDS 字符串等。
2. 共享字符串
当多个客户端传入相同的字符串参数时,Redis 会把相同字符串的内部指针指向同一内存地址,这些指针共享同一个字符串对象。这种优化可以减少内存占用,提高性能。
robj *lookupShared(const char *s, size_t len) {dictEntry *de = dictFind(server.shared.dict,s);if (de) {robj *shared = dictGetVal(de);return shared;}robj *shared = createStringObject(s,len);dictAdd(server.shared.dict, s, shared);return shared;
}robj *createShared(const char *ptr, size_t len) {robj *sobj = createObject(OBJ_STRING,sdsnewlen(ptr,len));sobj->encoding = OBJ_ENCODING_RAW; // 设置编码方式为RAWreturn sobj;
}
源码解释:这里有两个相关函数:lookupShared() 用于在 Redis 的共享字符串池中查找指定的字符串,如果字符串存在,则返回字符串对象;如果字符串不存在,则新建字符串对象并存储在共享字符串池中。createShared() 函数则是用于创建新的共享字符串对象。
3. 编码的优化
Redis 的 String 类型支持多种编码方式,如 INT、EMBSTR、RAW 等。根据不同的编码方式和数据类型,Redis 选择最适合的编码方式来储存数据,从而避免了冗余的存储空间。
int encodingType(robj *o) {if (o->encoding == OBJ_ENCODING_INT) {return OBJ_ENCODING_INT;} else if (o->encoding == OBJ_ENCODING_EMBSTR) {return OBJ_ENCODING_EMBSTR;} else {return OBJ_ENCODING_RAW;}
}void setStringObject(robj *o, const char *s, size_t len) {if (o->encoding == OBJ_ENCODING_INT) {// 释放原有的整数值空间decrRefCount(o);// 创建新的Raw编码字符串对象o = createStringObject(s,len);} else if (o->encoding == OBJ_ENCODING_EMBSTR) {// 释放原有的Embstr编码字符串空间sdsfree(o->ptr);o->ptr = zmalloc(len);memcpy(o->ptr, s, len);o->encoding = OBJ_ENCODING_RAW;} else {// 设置Raw编码字符串值o->ptr = sdscpylen(o->ptr, s, len);o->encoding = OBJ_ENCODING_RAW;}
}
源码解释:这里有两个相关函数:encodingType() 用于返回某个值采用的编码方式,可以检查一个字符串对象或列表对象采用的编码方式;另一个函数 setStringObject() 用于设置一个字符串对象的值,根据需要选择适当的编码方式。
4. 总结时刻
回答出来以上三点,表明你对 Redis 的 String 类型的源码是有研究的,而不是每天只顾 CRUD,只顾写业务。
另外,也能表明你的技术深度,面试官一定会对你另眼相看哟!加油!
相关文章:
Redis 底层对 String 的 3 个优化
Redis对 String 类型实现了很多优化,通过以下三个重要的优化点来解释: 1. 简单动态字符串(SDS) Redis 的 String 类型内部采用简单动态字符串(SDS)来管理字符串。相比于 C 语言的原生字符串,S…...

简约艺术签名小程序源码/流量主小程序源码/字节跳动抖音小程序
源码简介: 本源码为简约艺术签名小程序、流量主小程序以及字节跳动抖音小程序的源代码。该小程序是一款实用的工具,旨在帮助用户创建各种独特的艺术签名,以便在社交媒体平台上更好地展示用户的个性和创意。 源码链接: 网盘源码 …...
Ubuntu(kylin)挂载iso文件和配置apt本地源
版本说明:Ubuntu Server 16.04 LTS解决问题:解决在无任何互联网的环境下,安装软件时缺少依赖包的问题 方法一:通过虚拟机挂载 将镜像挂载到虚拟机以VMware Workstation为例,打开“虚拟机设置”,点击“CD/DVD”选项,将 “设备状态”中的“<...

wps表格求标准差怎么算?
在WPS表格中,要计算标准差,可以使用STDEV函数。标准差是一种衡量数据集合离散程度的统计指标。下面我将详细介绍如何使用STDEV函数来计算标准差。 STDEV函数的语法为:STDEV(range) 其中,range表示要计算标准差的数据范围&#x…...

安达发|制造企业生产排产现状和APS系统的解决方案
随着市场竞争的加剧,制造业企业面临着生产效率、成本控制和客户满意度等方面的巟大压力。在这种背景下,生产排产作为制造业的核心环节,对企业的生产经营具有重要意义。本文将针对制造业的生产排产现状进行分析,并提出相应的APS系统…...

Qt判断一个点在多边形内还是外(支持凸边形和凹变形)
这里实现的方法是转载于https://blog.csdn.net/trj14/article/details/43190653和https://blog.csdn.net/WilliamSun0122/article/details/77994526 来实现的,并且按照Qt的规则进行了调整。 以下实现方法有四种,每种方法的具体讲解在转载的博客中有说明&…...
MySQL导入数据库出现 Got error 168 from storage engine错误
“Got error 168 from storage engine” 是 MySQL 数据库的一个错误,通常是由于存储引擎发生了一些问题导致的。这个错误可能有多种原因引起。以下是一些可能的解决方法: 检查硬盘空间:确保目标数据库的服务器有足够的硬盘空间来执行导入操作…...

使用 VS Code 作为 VC6 的编辑器
使用 VS Code 作为 VC 6.0 的编辑器 由于一些众所周知的原因,我们不得不使用经典(过时)的比我们年龄还大的已有 25 年历史的 VC 6.0 来学习 C 语言。而对于现在来说,这个经典的 IDE 过于简陋,并且早已不兼容新的操作系…...

Peter算法小课堂—蠕动区间
蠕动区间 蠕动区间(尺取法、双游标)是一个经典的优化算法。 我们以毛毛虫🐛举例说明 具体的,我们看题目 例题 最小区间 这一题,我们用暴力法,复杂度O(N^2) 先给出暴力法代码 int ansn1; for(int tail…...

Vant和ElementPlus在vue的hash模式的路由下路由离开拦截使用Dialog和MessageBox失效
问题复现 ElementPlus:当点击返回或者地址栏回退时,MessageBox无效 <template><div>Element Plus Dialog 路由离开拦截测试</div><el-button type"primary" click"$router.back()">返回</el-button>…...

上海市通过区块链技术攻关 构建数字经济可信安全技术底座
日前,上海市印发《上海区块链关键技术攻关专项行动方案(2023—2025年)》(以下简称《行动方案》),提出到2025年,在区块链体系安全、密码算法等基础理论以及区块链专用处理器、智能合约、跨链、新…...
Java 面试题
昨天面试了两个Java开发程序员,问了一些问题,回答的不是很好,看看大家的回答如何,可以在评论区回复,测试下自己的水平。 A程序员: 1. 自我介绍一下; 2. 企业级和互联网行业都有那些项目经验,简…...

layui 表格 展开
一、表格嵌套表格(手风琴打开) <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>设备上下线统计</title><script type"text/javascript" src"../../../l…...

[尚硅谷React笔记]——第4章 React ajax
目录: 脚手架配置代理_方法一 server1.js开启服务器server1:App.js解决跨域问题:脚手架配置代理_方法二 server2.js开启服务器server2第一步:创建代理配置文件编写setupProxy.js配置具体代理规则:App.js运行结果&a…...

Richard Stallman 正在与癌症作战
导读为了纪念 GNU 项目成立 40 周年,自由软件基金会(FSF)已计划在 10 月 1 日(即GNU 40)为家庭、学生以及美国的其他人群组织一场黑客马拉松活动。 活动之前,GNU 项目于 9 月 27 日迎来了 40 岁生日&#…...

MathType7.4最新免费版(公式编辑器)下载安装包附安装教程
MathType是一款专业的数学公式编辑器,理科生专用的必备工具,可应用于教育教学、科研机构、工程学、论文写作、期刊排版、编辑理科试卷等领域。可视化公式编辑器轻松创建数学方程式和化学公式。兼容Office Word、PowerPoint、Pages、Keynote、Numbers 等7…...
如何支持h.265视频
前言 略 h.265视频 h.265是一种视频编码格式。 随着视频编码技术的发展,相比H.264, H.265同等画质体积仅为一半、带宽占用省一半、画质更细腻等诸多优势。 但Web浏览器还不支持H.265的解码播放,因此基于Web Assembly(封装FFmpeg)、JS解封装、Canvas投…...
vue 放大镜(简易)
目录 zoom组件 <template><div class"pic-img"><div class"img-container"><img ref"img" load"imgLoaded" :src"url" :style"overlayStyle" error"imgerrorfun"/><div cl…...

【计算机网络】第一章——概述
个人主页直达:小白不是程序媛 系列专栏:计算机网络基础 目录 前言 计算机网络概述 概念 功能 组成 分类 标准化工作 性能指标 速率 带宽 吞吐量 时延 时延带宽积 往返时延RTT 利用率 分层 为什么要分层? 分层的基本原则&am…...

vue实现在页面拖拽放大缩小div并显示鼠标在div的坐标
1、功能要求: 实现在一个指定区域拖拽div,并可以放大缩小,同时显示鼠标在该div里的坐标,如图可示 缩小并拖动 2、实现 <div class"div_content" ref"div_content"><div class"div_image" id"…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
离线语音识别方案分析
随着人工智能技术的不断发展,语音识别技术也得到了广泛的应用,从智能家居到车载系统,语音识别正在改变我们与设备的交互方式。尤其是离线语音识别,由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力,广…...

Unity VR/MR开发-VR开发与传统3D开发的差异
视频讲解链接:【XR马斯维】VR/MR开发与传统3D开发的差异【UnityVR/MR开发教程--入门】_哔哩哔哩_bilibili...
大模型真的像人一样“思考”和“理解”吗?
Yann LeCun 新研究的核心探讨:大语言模型(LLM)的“理解”和“思考”方式与人类认知的根本差异。 核心问题:大模型真的像人一样“思考”和“理解”吗? 人类的思考方式: 你的大脑是个超级整理师。面对海量信…...