【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 4000008=3.2106 ,因此一个指针 可以用 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越大,压缩率也就越高。但是,在压缩和词项查找速度之间必须要保持某种平衡。否则会导致查找速率偏慢。

除此之外,还有一种前端编码方式的压缩,也就是将上面多个词的公共部分提取出来,这样能减少很多的空间。,这里就不过多讲解了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/44873.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

李沐pytorch学习-卷积网络及其实现

一、卷积概述 1.1 基本定义 卷积计算过程如图1所示,即输入矩阵和核函数(filter)对应的位置相乘,然后相加得到输出对应位置的数。 图1. 卷积计算过程 该过程可以形象地从图2中展现。 图2. 二维卷积示意图 1.2 实现互相关运算的代…

Python tkinter Notebook标签添加关闭按钮元素,及左侧添加存储状态提示图标案例,类似Notepad++页面

效果图展示 粉色框是当前页面,橙色框是鼠标经过,红色框是按下按钮,灰色按钮是其他页面的效果; 存储标识可以用来识别页面是否存储:例如当前页面已经保存用蓝色,未保存用红色,其他页面已经保存用…

2023最新版本~KEIL5使用C++开发STM32

先看效果 开始教学 因为是第一次写这个配置教程 我会尽量详细些 打开一个Keil工程 移除本地core 添加在线core 第一次编译代码 不会有报错 修改main.c文件类型为C 点击魔术棒 把ARM编译器修改为V6 第二次编译会报错语法不兼容 我把汇编部分的这些代码做了…

基于IMX6ULLmini的linux裸机开发系列九:时钟控制模块

时钟控制模块 核心 4个层次配置芯片时钟 晶振时钟 PLL与PFD时钟 PLL选择时钟 根时钟/外设时钟 系统时钟来源 RTC时钟源:32.768KHz 系统时钟:24MHz,作为芯片的主晶振使用 PLL和PFD倍频时钟 7路锁相环电路(每个锁相环电路…

【IMX6ULL驱动开发学习】05.字符设备驱动开发模板(包括读写函数、poll机制、异步通知、定时器、中断、自动创建设备节点和环形缓冲区)

一、 字符设备驱动简介 字符设备是Linux驱动中最基本的一类设备驱动,字符设备就是一个一个字节,按照字节流进行读写操作的设备,读写数据是分先后顺序的。比如常见的点灯、按键、IIC、SPI、LCD 等等都是字符设备,这些设备的驱动就叫…

centos8 使用phpstudy安装tomcat部署web项目

系统配置 1、安装Tomcat 2、问题 正常安装完Tomcat应该有个配置选项,用来配置server.xml web.xml 还有映射webapps路径选项,但是我用的这个版本并没有。所以只能曲线救国。 3、解决 既然没有配置项,那就只能按最基本的方法配置&#xff0c…

关于Coursera网站视频无法观看

文章目录 前言找Ip 改hosts验证 前言 众所周知,coursera是很不错的学习网站,但由于国内访问限制,导致我的学习之路举步维艰 在科学上网彻底崩盘后,终于断了我的学习热情(真的很想骂人) 网站只能登入&#…

深入浅出Pytorch函数——torch.nn.init.sparse_

分类目录:《深入浅出Pytorch函数》总目录 相关文章: 深入浅出Pytorch函数——torch.nn.init.calculate_gain 深入浅出Pytorch函数——torch.nn.init.uniform_ 深入浅出Pytorch函数——torch.nn.init.normal_ 深入浅出Pytorch函数——torch.nn.init.c…

【无标题】WIN11下 ESP8266 _RTOS_SDK3.0以上开发环境搭建(记录及避坑必看)

前提参考文档 1、乐鑫官网: https://docs.espressif.com/projects/esp8266-rtos-sdk/en/latest/get-started/index.html 官网上有如何搭建windows linux macos 三种环境,以及如何配置Eclipse去编译和开发项目(如何安装Eclipse环境&#xff0…

微人事 登录问题完善

重启服务端的时候,发现前端页面会操作不了,这样后端session会失效,我们就需要让页面重新跳转到登录页 springsecurity配置类后端配置 前端拦截器进行拦截跳转

WPF中的UseLayoutRounding和SnapsToDevicePixels

WPF中的UseLayoutRounding和SnapsToDevicePixels 最近在调试项目中的UI时发现几个诡异问题: Grid容器里的GridSplitter设置粗细一样, 但截屏放大后发现线条不一样粗并且明暗不一致,导致打印出来有问题。 自定义控件的边缘在某些窗体中显示模…

【STM32RT-Thread零基础入门】 5. 线程创建应用(线程创建、删除、初始化、脱离、启动、睡眠)

硬件:STM32F103ZET6、ST-LINK、usb转串口工具、4个LED灯、1个蜂鸣器、4个1k电阻、2个按键、面包板、杜邦线 文章目录 前言一、线程管理接口介绍二、任务:使用多线程的方式同时实现led闪烁和按键控制喇叭(扫描法)1. RT-Thread相关接…

使用mysql:5.6和owncloud镜像构建个人网盘

一、拉取镜像 使用docker拉取mysql:5.6和owncloud的镜像 [rootexam ~]# docker pull mysql:5.6 [rootexam ~]# docker pull owncloud 运行镜像生成容器实例 [rootexam ~]# docker run -d --name mydb1 --env MYSQL_ROOT_PASSWORD123456 mysql:5.6 a184c65b73ff993cc5cf86f…

700. 二叉搜索树中的搜索

给定二叉搜索树(BST)的根节点 root 和一个整数值 val。 你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null 。 示例 1: 输入:root [4,2,7,1,3], val 2 输出:[2,1,3]…

Hive on Spark (1)

spark中executor和driver分别有什么作用? Spark中Executor 在 Apache Spark 中,Executor 是分布式计算框架中的一个关键组件,用于在集群中执行具体的计算任务。每个 Executor 都在独立的 JVM 进程中运行,可以在集群的多台机器上…

html常见兼容性问题

1. png24位的图片在iE6浏览器上出现背景 解决方案:做成PNG8,也可以引用一段脚本处理. 2. 浏览器默认的margin和padding不同 解决方案:加一个全局的 *{margin:0;padding:0;} 来统一。 3. IE6双边距bug:在IE6下,如果对…

vue3生命周期

原理 vue3也提供了Composition API形式的生命周期钩子,与vue2.x中钩子对应关系如下: beforeCreate setup() created setup() beforeMountonBeforeMount mountedonMounted beforeUpdateonBeforeUpdate updat…

【华为OD机试】单词重量【2023 B卷|100分】

【华为OD机试】-真题 !!点这里!! 【华为OD机试】真题考点分类 !!点这里 !! 题目描述 每个句子由多个单词组成,句子中的每个单词的长度都可能不一样, 我们假设每个单词的长度Ni为该单词的重量,你需要做的就是给出整个句子的平均重量V。 输入描述 无 输出描述 无 样例1…

docker的安装与基础使用

一.docker简介 1)什么是docker Docker是一种用于构建、打包和运行应用程序的开源平台。它基于操作系统级虚拟化技术,可以将应用程序和其依赖的库、环境等资源打包到一个可移植的容器中,形成一个轻量级、独立的可执行单元。 开发者在本地编…

MySQL流程控制

流程控制 顺序结构: 程序从上往下依次执行分支结构: 程序按条件进行选择执行,从两条或多条路径中选择一条执行。循环结构: 程序满足一定条件下,重复执行一组语句 针对于MySQL的流程控制语句主要有3类。注意&#xff…