【Golang系统开发】搜索引擎(2) 压缩词典
写在前面
这篇文章我们就给出一系列的数据结构,使得词典能达到越来越高的压缩比。当然,和倒排索引记录表的大小相比,词典只占据了非常小的空间。那么为什么要对词典进行压缩呢?
这是因为决定信息检索系统的查询响应时间的一个重要因素就是磁盘的访问次数,而如果有部分词典存在于磁盘上,那么在处理查询时就需要更多的磁盘访问次数。 因此,词典压缩的主要目的是可以将词典放在内存当中,这样才会获得很高的查询吞吐率。那么如何能将更多的词典压缩在有限的内存中呢?
1. 词典看成单一字符串
最简单的词典的数据结构就是整个词典采用定长数组来存储且所有词项按照词典序排序。假设对每个词项采用20B的固定长度存储,文档频率采用4B存储,词项到倒排索引也采用4B存储。这里的4B指针能够访问4GB的地址空间(4B–>32位–>2的32次方–>4GB)。

这样即使我们的词典有 四百万 个,我们所占的内存就只是 4,000,000 * (20+4+4) B = 112 MB,只是一百多兆而已,这非常的压缩。
但是很明显,采用这种定长方法来存储词典存在空间浪费。一个中文三个字节,很多情况下我们的词典只是两个中文,也就是六个字节,所以会有 14字节的浪费 。但是如果是一些特定的词语超过了20字节(比如中南财经政法大学),这里又存不下去。一种解决上述缺陷的方法是将所有的词项存成一个长字符串,并给每个词项增加一个定位指针,他在指向下一词项的同时也表示这当前词项的结束。 同以往一样,仍然可以通过二分查法定位到所需的词项,但是现在的表更小了。
由于每20B能够节省下12B,所以相当于前面的定长机制而言,这种机制能够在词项存储上节省大约60%的空间。当然,以上计算没有包括指向词项的指针所消耗的空间。所有的这些指针寻址的空间大小为 400000 ∗ 8 = 3.2 ∗ 1 0 6 400000 * 8 = 3.2 * 10^6 400000∗8=3.2∗106 ,因此一个指针 可以用 log 2 ( 3.2 ) ∗ 1 0 2 \log_2(3.2)*10^2 log2(3.2)∗102 约等于 22 位 或者 3B来表示

将整个词条看成一个长字符串的词典存储方式,其中指向下一词项的指针同时也标志着当前词项的结束。
在这种方式下,词条就将所有上述的 4,000,000 * (20+4+4) B = 112 MB 压缩到了 4,000,000 * (3+4+4+8) B = 76 MB ,这个 8 指的是每个词项的平均长度。这种就从 112MB --> 76MB 大大降低了1/3
2. 按块存储
我们可以根据上一节的结果进行再一次的压缩:将长字符串中的词项进行分组变成大小为k的块,即k个词项一组,然后对每个块只保留第一个词项的指针。同时用一个额外字典将每个词项的长度存储在每个词项的首部。因此,每个块而已,可以减少k-1个词项指针,但是需要额外的kB来保存k个词项的首部。

因此,对每个块而言,可以减少k-1个词项指针,到那时需要额外的kB来保存k个词项的长度。对于k=4,词项指针的存储将会减少 (k-1) * 3 = 9B ,但是同时需要增加 k=4B 来存储词项的长度。因此在按块存储的方式下,没k=4个词项的方式下,每k=4个词项就会节省出5B,所以总共节省的空间位 400000 * 1/4 * 5 = 5 MB,也就再次减少了5MB,在 76MB 的基础上又少了 71MB。
显然,k越大,压缩率也就越高。但是,在压缩和词项查找速度之间必须要保持某种平衡。否则会导致查找速率偏慢。
除此之外,还有一种前端编码方式的压缩,也就是将上面多个词的公共部分提取出来,这样能减少很多的空间。,这里就不过多讲解了。
相关文章:
【Golang系统开发】搜索引擎(2) 压缩词典
写在前面 这篇文章我们就给出一系列的数据结构,使得词典能达到越来越高的压缩比。当然,和倒排索引记录表的大小相比,词典只占据了非常小的空间。那么为什么要对词典进行压缩呢? 这是因为决定信息检索系统的查询响应时间的一个重…...
clickhouse修改默认密码
1.明文密码 vim /etc/clickhouse-server/users.xml找到下面的语句,增加明文密码 <password>123456789</password> 2. sha256密码 # echo -n 123456789 | openssl dgst -sha256 (stdin) 15e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225 修改…...
基于java在线捐赠系统设计与实现
摘要 近年来,随着网络的快速发展,由于网络的开放性和便利性,具有广阔的发展前景。 本文设计并实现了医药捐赠系统。通过分析确定由两个不同的用户组成,每个用户具有不同的功能。它还可以帮助用户在线求助、申请项目、发表留言等&a…...
【前端】vscode javascript 代码片段失效问题解决
1. 文件--首选项--用户代码片段-vue.json : 添加 // { // // Place your global snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and // // description. Add comma separated ids of the languages where the snippet is app…...
AE-卡通人物解说动画视频的制作
目录 1.导入卡通人物图片和音频文件 2.新建合成 3.在卡通人物图片上添加效果和表达式 4.在音频文件上添加效果和表达式 5.将卡通人物中的 CC Split2 中分割1 表达式链接到滑块中 6.卡通人物根据音频文件自动匹配口型。 AE制作卡通人物解说视频,卡通人物口型根据…...
Linux 查看日志
在 Linux 中,内核日志使用 printk 函数进行输出。你可以通过以下方法查看 printk 的日志: 使用 dmesg 命令: dmesg 这个命令会显示内核环缓冲区中的日志消息,包括使用 printk 输出的消息。你可以通过滚动浏览输出来查看完整的日志…...
使用IO多路复用select完成TCP循环服务器接收客户端消息并打印
服务器 客户端 结果...
unity之Input.GetKeyDown与Input.GetKey区别
文章目录 Input.GetKeyDown与Input.GetKey区别 Input.GetKeyDown与Input.GetKey区别 Input.GetKey 和 Input.GetKeyDown 是 Unity 中用于检测按键状态的两个不同函数。它们之间的区别在于何时触发。 Input.GetKey(KeyCode key): 这个函数会在用户按住指定的键时触发࿰…...
excel 核心快捷键用法
1、wps怎样只复制公示计算出来的数据 1.1、按下快捷键“CtrlC”,复制该单元格。 1.2、按下快捷键“ShiftCtrlV”,即“粘贴为数值”,即可只复制数字而不复制该单元格的公式 1.3、wps怎样只复制公示计算出来的数据_百度知道https://zhidao.baid…...
postgresql
源码安装 ./configure --prefix/apps/pgsql make world -j4 make install-world useradd -s /bin/bash -m -d /home/postgres postgres echo -e ‘123456\n123456’ | passwd postgres mkdir -pv /pgsql/data chown postgres:postgres /pgsql/data/ 设置环境变量 vim /etc/…...
AutoSAR配置与实践(基础篇)3.2 BSW中的I/O架构和模块详解
传送门 -> AUTOSAR配置与实践总目录 AutoSAR配置与实践(基础篇)3.2 BSW中的I/O架构和模块详解 一、 BSW中的I/O架构和模块详解1.1 I/O 模块构成1.2 各子模块功能详解二、举例说明I/O 模块如何配合完成信号采集2.1 硬件处理先行 (step1-4)2.2 AUTOSAR软件登场(step 5-7)2.3…...
基于Java+SpringBoot+Vue的学校田径运动会管理系统【源码+论文+演示视频+包运行成功】
博主介绍:✌擅长Java、微信小程序、Python、Android等,专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇🏻 不然下次找不到哟 Java项目精品实战案…...
使用 Visual Studio Code Docker 工具调试 .NET 容器
作者:Chet Husk 排版:Alan Wang Visual Studio Code Docker 工具已发布1.26.0版本,这个版本为使用 .NET SDK 构建和调试容器映像提供了内置支持。 VS Code 中的 Docker 调试 Visual Studio Code Docker 工具使开发人员可以轻松入门容器。它…...
AI引擎助力,CamScanner智能高清滤镜开启扫描新纪元!
文章目录 ⭐ 写在前面⭐ 突破图像处理难点:扫描全能王的独特优势⭐ 耳听为虚,眼见为实⭐ 产品背后的主要核心:AI-Scan助力⭐ 深度学习助力智能文档处理的国际化进程⭐ 品味智能文档处理的轻松与精准 ⭐ 写在前面 在数字化快速发展的今天&…...
opencv进阶07-支持向量机cv2.ml.SVM_create()简介及示例
支持向量机(Support Vector Machine,SVM)是一种二分类模型,目标是寻找一个标准(称为超平面)对样本数据进行分割,分割的原则是确保分类最优化(类别之间的间隔最大)。当数据…...
LA@n维向量@解析几何向量和线性代数向量
文章目录 概念n维向量向量类型实向量和复向量行向量和列向量行列向量的转换特殊向量向量运算 矩阵的向量分块👺 解析几何向量和线性代数向量👺向量空间 n n n维向量空间 n n n维空间的 n − 1 n-1 n−1维超平面 概念 n维向量 由 n n n个有次序的数 a …...
go 协程并发数控制
错误的写法: 这里的<-ch 是为了从channel 中读取 数据,为了不使channel通道被写满,阻塞 go 协程数的创建。但是请注意,go workForDraw(v, &wg) 是不阻塞后续的<-ch 执行的,所以就一直go workForDraw(v, &…...
MySQL的安装以及卸载
下载官网 https://www.mysql.com/ 切到下载tab页 找到 MySQL Community Server 或者 MySQL Community (GPL) Downloads --> MySQL Community Server 点击download按钮: 点击download进入下载页面选择No thanks, just start my download就可以开始下载了。 下…...
LRU算法与Caffeine、Redis中的缓存淘汰策略
推荐阅读 AI文本 OCR识别最佳实践 AI Gamma一键生成PPT工具直达链接 玩转cloud Studio 在线编码神器 玩转 GPU AI绘画、AI讲话、翻译,GPU点亮AI想象空间 资源分享 「java、python面试题」来自UC网盘app分享,打开手机app,额外获得1T空间 https://dr…...
HTML笔记(3)
表单标签 用于登录、注册界面,以采集用户输入的信息,把信息采集到之后,用户一点按钮,就会把这些信息发送到服务端,服务端就可以把这些数据存储到数据库,所以表单是一个非常重要的html标签,它主要…...
利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...
基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
LLMs 系列实操科普(1)
写在前面: 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容,原视频时长 ~130 分钟,以实操演示主流的一些 LLMs 的使用,由于涉及到实操,实际上并不适合以文字整理,但还是决定尽量整理一份笔…...
ThreadLocal 源码
ThreadLocal 源码 此类提供线程局部变量。这些变量不同于它们的普通对应物,因为每个访问一个线程局部变量的线程(通过其 get 或 set 方法)都有自己独立初始化的变量副本。ThreadLocal 实例通常是类中的私有静态字段,这些类希望将…...
Qt Quick Controls模块功能及架构
Qt Quick Controls是Qt Quick的一个附加模块,提供了一套用于构建完整用户界面的UI控件。在Qt 6.0中,这个模块经历了重大重构和改进。 一、主要功能和特点 1. 架构重构 完全重写了底层架构,与Qt Quick更紧密集成 移除了对Qt Widgets的依赖&…...
Netty自定义协议解析
目录 自定义协议设计 实现消息解码器 实现消息编码器 自定义消息对象 配置ChannelPipeline Netty提供了强大的编解码器抽象基类,这些基类能够帮助开发者快速实现自定义协议的解析。 自定义协议设计 在实现自定义协议解析之前,需要明确协议的具体格式。例如,一个简单的…...
