【文档搜索引擎】缓冲区优化和索引模块小结

news2024/12/24 16:45:17

开机之后,首次制作索引会非常慢,但后面就会快了
重启机器,第一次制作又会非常慢
这是为什么呢?

在 parserContent 里面,我们进行了一个读文件的操作

  • 计算机读取文件,是一个开销比较大的操作,

缓存
parserContent 的核心操作,就是读取文件,从磁盘进行访问,操作系统就会对“经常读取的文件”进行缓存
首次运行的时候,当前的这些 Java 文档,都没有在内存中缓存,因此读取的时候只能直接从硬盘上读取(相对耗时)
后面再运行的时候,由于前面已经读取过这些文档了,这些文档都在操作系统中其实已经有了一份缓存(在内存中),这次的读取不必直接读取硬盘,而是直接读内存的缓存(速度就会快很多)

缓冲区优化

我们可以通过使用一些线程类,来将缓存加进去,提高读取速率。

我们使用的读文件操作是:

int ret = fileReader.read();
  • 这里的 read() 每次都是在读磁盘,速度就会比较慢
  • 相比之下,我们可以在这里将 fileReader 的内容提前就读取到内存之中,然后每次调用 read() 的时候,就可以直接从内存中进行读取了

BufferedReader

BufferedReader 可以搭配 FileReader 来使用。我们只需要在构造 BufferedReader 的时候,把 FileReader 实例给设置进去就可以了

  • BufferedReader 内部就会内置一个缓冲区,就能够自动的把 FileReader 中的一些内容预读到内存中,从而减少直接访问磁盘的次数
BufferedReader bufferedReader = new BufferedReader(new FileReader(f))

image.png|498
通过 BufferedReader 类可以看到,它的缓冲区默认值是 8192(8k),我们可以将其设置大一点。我们就将 BufferedReader 的第二个参数,手动设置一下大小

BufferedReader bufferedReader = new BufferedReader(new FileReader(f), 1024 * 1024)
  • 手动将缓冲区设置为 1M 大小

索引加载逻辑

image.png|544

我们的索引加载逻辑,就是要从这两个文件进行加载。这里的文件保存好的索引数据,再给它保存到内存中,把它还原成内存中的那两个数据结构

// 正排索引
private ArrayList<DocInfo> forwardIndex = new ArrayList<>();  
  
// 倒排索引
private HashMap<String, ArrayList<Weight>> invertedIndex = new HashMap<>();

我们可以验证一下这个索引加载

public static void main(String[] args) {  
    Index index = new Index();  
    index.load();  
    System.out.println("索引加载完毕!");  
}
  • 我们将断点打到打印那一行,然后观察调试信息 image.png|552
  • 可以看到两个数据结构都被还原到内存中了

索引模块小结

1. Parser 类

作用

  1. 针对递归的方式,枚举除了所有的 HTML 文件

  2. 针对这里的每个 HTML 进行解析

    • 标题:直接使用的文件标题
    • URL:基于文件路径进行简单的拼接(离线文档和线上文档的路径关系)
    • 正文:核心操作——去标签(将这里的 HTML 标签都去掉)。简单粗暴的方式实现,使用 <> 作为“是否要拷贝数据”的开关
  3. 将这里的解析结果,放到 Index 类中(addDoc 方法)

通过这个 Parser 类,最主要的事情,还是辅助 Index 类,来完成索引制作的过程

Parser 类主要就是:

  1. 做准备工作
  2. 调用 Index
  3. 通过这个类,作为完整应用程序的入口类
    后续需要制作索引,就直接调用 Parsermain 方法即可

单线程 vs 多线程

单线程制作索引比较低效,速度比较慢。改进成多线程之后,速度就明显有了提升。

我们要明确地描述出,这些文档什么时候能处理完。如果没处理完,我们是不能轻易地保存索引的,必须得保证所有的文档都解析完毕了、在索引中加载完毕了,才能够真正地保存在文件当中。

  • 所以我们使用 CountDownLatch 来计数。只有当所有的文档都处理完毕,都已经调用了 countDown 方法,撞线了,然后我们才能执行保存索引的操作

读文件缓冲区

在 Parser 类中,涉及到大量的读文件操作,我们通过实验得出:首次加载索引的时候速度会慢一些,后面再读就会变快了。

  • 因为第一次读的时候,这些文档都在磁盘上,内存中没有缓存,所以我们读的速度就会慢一些
  • 读过一次之后,很多文件就会操作系统自动缓存。之后我们再加载索引的时候,这里的文档就不用都在磁盘中读了,相当一部分可直接在内存中读取,这样速度就会变快

2. Index 类

核心属性

  1. 正排索引
private ArrayList<DocInfo> forwardIndex = new ArrayList<>();
  • 每个 DocInfo 都表示一个文档,在这个文档里面就包含了 idtitleurlcontent
  1. 倒排索引
private HashMap<String, ArrayList<Weight>> invertedIndex = new HashMap<>();
  • 每个键值对,就表示这个词在哪些文档中出现过
  • Weight 不仅仅是包含了文档 id,还包含了权重信息。权重当前是通过词出现的频次来计算的(标题中出现的次数 * 10 + 正文中出现的次数

核心方法

  1. 查正排
    直接按照下标来取 ArrayList<DocInfo> 中的元素即可

  2. 查倒排
    直接按照 key 来取 HashMap<String, ArrayList<Weight>>value 即可

  3. 添加文档
    通过 Parser 类,在构建索引的时候,调用该方法

  • 构建正排,构造一个 DocInfo 对象,给其添加到正排索引末尾
  • 构建倒排,先进行分词,统计词频,遍历分词结果,去更新倒排索引中对应的倒排拉链(注意其中的线程安全问题)
  1. 保存索引
    基于 JSON 格式,把索引数据保存到指定文件中

  2. 加载索引
    基于 JSON 格式,对数据进行解析。把文件中的内容读出来,解析到内存中

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

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

相关文章

html+css网页设计 旅游 移动端 雪花旅行社4个页面

htmlcss网页设计 旅游 移动端 雪花旅行社4个页面 网页作品代码简单&#xff0c;可使用任意HTML辑软件&#xff08;如&#xff1a;Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作&#xff09;。 获取源码 …

3 JDK 常见的包和BIO,NIO,AIO

JDK常见的包 java.lang:系统基础类 java.io:文件操作相关类&#xff0c;比如文件操作 java.nio:为了完善io包中的功能&#xff0c;提高io性能而写的一个新包 java.net:网络相关的包 java.util:java辅助类&#xff0c;特别是集合类 java.sql:数据库操作类 IO流 按照流的流向分…

从零创建一个 Django 项目

1. 准备环境 在开始之前&#xff0c;确保你的开发环境满足以下要求&#xff1a; 安装了 Python (推荐 3.8 或更高版本)。安装 pip 包管理工具。如果要使用 MySQL 或 PostgreSQL&#xff0c;确保对应的数据库已安装。 创建虚拟环境 在项目目录中创建并激活虚拟环境&#xff…

ubuntu20.04安装imwheel实现鼠标滚轮调速

ubuntu20.04安装imwheel实现鼠标滚轮调速 Ubuntu 系统自带的设置中仅具备调节鼠标速度的功能&#xff0c;而无调节鼠标滚轮速度的功能。其默认的鼠标滚轮速度较为缓慢&#xff0c;在查看文档时影响尚可接受&#xff0c;但在快速浏览网页时&#xff0c;滚轮速度过慢会给用户带来…

GitLab的安装与卸载

目录 GitLab安装 GitLab使用 使用前可选操作 修改web端口 修改Prometheus端口 使用方法 GitLab的卸载 环境说明 系统版本 CentOS 7.2 x86_64 软件版本 gitlab-ce-10.8.4 GitLab安装 Gitlab的rpm包集成了它需要的软件&#xff0c;简化了安装步骤&#xff0c;所以直接…

简单工厂模式和策略模式的异同

文章目录 简单工厂模式和策略模式的异同相同点&#xff1a;不同点&#xff1a;目的&#xff1a;结构&#xff1a; C 代码示例简单工厂模式示例&#xff08;以创建图形对象为例&#xff09;策略模式示例&#xff08;以计算价格折扣策略为例&#xff09;UML区别 简单工厂模式和策…

脑肿瘤检测数据集,对9900张原始图片进行YOLO,COCO,VOC格式的标注

脑肿瘤检测数据集&#xff0c;对9900张原始图片进行YOLO&#xff0c;COCO&#xff0c;VOC格式的标注 数据集分割 训练组 70&#xff05; 6930图片 有效集 20&#xff05; 1980图片 测试集 10&#xff05; 990图片 预处理 静态裁剪&#xff1a; 24-82&…

YOLOv8 | 训练自定义数据集

目录 1 处理数据集1.1 数据集格式介绍1.2 划分数据集1.3 在 YOLOv8 中配置数据集 2 训练 YOLOv8 模型2.1 模型训练代码2.2 开启 TensorBoard 若尚未部署 YOLOv8&#xff0c;则可参考这篇博客&#xff1a; YOLOv8 | Windows 系统下从零开始搭建 YOLOv8 项目环境 1 处理…

Java设计模式 —— 【结构型模式】外观模式详解

文章目录 概述结构案例实现优缺点 概述 外观模式又名门面模式&#xff0c;是一种通过为多个复杂的子系统提供一个一致的接口&#xff0c;而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口&#xff0c;外部应用程序不用关心内部子系统的具体的细节&#xff0c;这…

可编辑99PPT | 智能工厂整体规划方案及实施细部方案

荐言分享&#xff1a;智能工厂是利用物联网、大数据、人工智能等先进技术&#xff0c;实现生产过程自动化、智能化和柔性化的现代工厂。本整体规划方案旨在通过整合信息技术、自动化技术、人工智能技术和物联网技术&#xff0c;构建一个高效、灵活、绿色、可持续的生产环境&…

Allegro17.4创建异形焊盘速通

Allegro17.4创建异形焊盘速通 打开Padstack Editor 17.4&#xff0c;新建焊盘&#xff0c;以标贴焊盘为例: 该标贴焊盘是在底面&#xff0c;选择END LAYRE &#xff0c;选择 Shape symbol Geometry&#xff0c;Shape symbol选择框右边有选择键&#xff0c;跳到Library Shape S…

多行为级联24|多行为推荐的超图增强级联图卷积网络

挂到arxiv上的&#xff0c;多行为级联超图加对比学习,超图是针对单个行为的&#xff0c;而不是针对多个行为的。参考的类似工作是CRGCN加MBSSL。这两篇我都做了论文阅读&#xff0c;&#xff08;CRGCN正在路上&#xff0c;MBSSL是我的第一篇论文阅读帖子&#xff09;推荐系统论…

利用.NET Upgrade Assitant对项目进行升级

本教程演示如何把WPF程序从 <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>升级到<TargetFramework>net8.0-windows</TargetFramework>. 下载并安装.NET Upgrade Assistant - Visual Studio Marketplace Supported .NET upgrades: .NET Frame…

Vue2四、 scoped样式冲突,data是一个函数,组件通信-父传子-子传父-非父子

组件通信 1. 父组件通过 props 将数据传递给子组件 2. 子组件利用 $emit 通知父组件修改更新 父--->子 子--->父

第146场双周赛:统计符合条件长度为3的子数组数目、统计异或值为给定值的路径数目、判断网格图能否被切割成块、唯一中间众数子序列 Ⅰ

Q1、统计符合条件长度为3的子数组数目 1、题目描述 给你一个整数数组 nums &#xff0c;请你返回长度为 3 的子数组&#xff0c;满足第一个数和第三个数的和恰好为第二个数的一半。 子数组 指的是一个数组中连续 非空 的元素序列。 2、解题思路 我们需要在给定的数组 nums…

PSDK的编译与ROS包封装

本文档讲述在NIVIDIA开发板上使用大疆提供的Payload SDK获取无人机实时GPS信息的方法&#xff0c;以及基于Payload SDK发布ROS GPS话题信息的方法。 文章目录 0 实现目标1 Payload SDK1.1 PSDK 源码的编译1.2 PSDK 的使用 2 遥测数据的读取2.1 示例代码结构2.2 读取机载GPS信息…

铝电解电容使用寿命

铝电解电容寿命问题 铝电解电容为什么会失效&#xff1f;铝电解电容失效与那些因素有关&#xff1f;电解电容寿命如何计算&#xff1f; 1铝电解电容为什么会失效&#xff1f; 电容都是由两个导电板并排放到一起就构成了。正极是铝&#xff08;阳极箔&#xff09;&#xff0c;…

用Python PySide6 复刻了两软件UI 做下练习

图样 1 代码 1&#xff1a; # -*- coding: utf-8 -*-import sys from PySide6.QtCore import (QCoreApplication, QMetaObject, QRect, QDate) from PySide6.QtGui import QIcon, QPixmap, QColor from PySide6.QtWidgets import (QApplication, QDialog, QLineEdit, QPushBut…

安装MongoDB,环境配置

官网下载地址&#xff1a;MongoDB Shell Download | MongoDB 选择版本 安装 下载完成双击打开 点击mongodb-windows-x86_64-8.0.0-signed 选择安装地址 检查安装地址 安装成功 二.配置MongoDB数据库环境 1.找到安装好MongoDB的bin路径 复制bin路径 打开此电脑 -> 打开高级…

Spring学习(一)——Sping-XML

一、Spring的概述 (一)什么是Spring? Spring是针对bean对象的生命周期进行管理的轻量级容器。提供了功能强大IOC、AOP及Web MVC等功能。Spring框架主要由七部分组成&#xff1a;分别是 Spring Core、 Spring AOP、 Spring ORM、 Spring DAO、Spring Context、 Spring Web和 S…