【数据结构】比较顺序表和链表的区别(优缺点),细讲CPU高速缓存命中率

news2024/10/8 17:19:09

目录

一、顺序表和链表的区别【表格】

二、顺序表优缺点

三、链表优缺点

四、缓存命中率(缓存利用率)

❥ 主存和本地二级存储

❥ 寄存器和三级缓存

❥ 顺序表缓存命中率

❥ 链表缓存命中率


一、顺序表和链表的区别【表格】

不同点顺序表链表(带头双向循环链表)
存储空间上物理上一定连续逻辑上连续,但物理上不一定连续
随机访问(用下标随机访问)支持   复杂度为O(1)不支持   复杂度为O(N)
任意位置插入或者删除元素可能需要搬移元素,效率低  复杂度为O(N)只需要修改指针的指向
插入动态顺序表,空间不够时需要扩容没有容量的概念
应用场景元素高效存储+频繁访问频繁插入和删除任意位置
缓存利用率

二、顺序表优缺点

优势

  • 能够通过下标进行随机访问
  • 物理上一定连续
  • 缓存利用率高

缺点

  • 扩容有消耗。扩容分为原地扩容和异地扩容,当为异地扩容时,消耗容量更多,因为还要进行数据的拷贝到新的空间,然后再释放掉原来的空间。
  • 扩容还有可能存在空间浪费。例如:开辟了100个空间,却只用了80个,浪费了20个空间。
  • 在插入删除时需要移动大量的元素

三、链表优缺点

优势

  • 可以任意位置插入和删除元素
  • 没有扩容的消耗,可以按需申请和释放
  • 不浪费空间

缺点

  • 不能用下标随机访问。所以链表排序意义不大,不如用数组进行排序(因为不能随机访问)
  • 缓存利用率低

所以说,顺序表和链表是互补的线性结构

四、缓存命中率(缓存利用率)


❥ 主存和本地二级存储

下图1是计算机存储器的层次结构。计算机的内部存储体系分为很多层,其中有两个使我们所熟知的,分别是

  • 主存:也就是电脑的内存
  • 本地磁盘:也就是硬盘

内存和硬盘的区别:

  • 内存:带电存储,速度很快,一个电脑内存一般是8/16G。
  • 硬盘:不带电存储,速度较慢。

虽然他们的区别是速度快慢问题,但本质区别是他们是否带电存储。

那何为带电不带电存储呢?

举个例子 ! ! !

        假设我们正在word上写笔记,这时候如果我们把电脑里的电池扣掉,那么正在word上写的笔记就会消失,再打开电脑就需要我们重新再写,为什么呢?

        这是因为我们写的笔记不是存在硬盘中,而是存在内存。

        为什么不存在硬盘呢?

        是因为硬盘的速度比较慢。

        那什么情况下它才会存在硬盘中呢?

        我们点击左上角的保存(或者直接ctrl+s),鼠标转两个圈圈(转圈说明速度较慢),这样就会保存到文件中,也就保存到了硬盘当中。

        若是存好之后我们又想修改一下我们的笔记,那修改之后的内容是不会存到文件中的,需要我们再次进行保存。

所以金字塔越往下存储容量越大,访问速度越来越慢,成本价格也越来越低。


❥ 寄存器和三级缓存

除此之外,我们发现每个电脑都还有一个寄存器和三级缓存。

补充:CPU和寄存器定义

  • CPU(中央处理器)是一块超大规模的集成电路,它是计算机的运算核心和控制核心。它由控制单元、运算单元和存储单元组成,负责解释计算机指令和处理软件中的数据。
  •  寄存器是位于CPU内部的一种物理存储器,用于高速存储指令和数据,设计目的是在CPU内部快速访问这些存储区域。

我们已经有了内存,且内存速度也还行,为什么还要有三级缓存呢?

分析如下:

代码:

int a = 0;
++a;

转到反汇编(汇编就是对应的指令),如下图所示:

我们定义了变量a,这个变量i是存储在内存中,现在对a执行下一步指令(即++a)。

那么谁来对i执行++a指令呢?

是CPU。CPU可以执行各种各样的指令(加减乘除,异或等)。

上图我们可知:++a转到反汇编,分为三步执行:

  • 首先它不是直接对内存a的位置进行++,它是把a从内存中读取出来,存储到eax这个寄存器
  • 然后执行inc eax指令,对寄存器中的值进行自增
  • 最后再把寄存器中自增完的值返回到ptr[a]这个位置。

为什么要这样做呢?

是因为它们不同频,cpu运行的速度太快,如果它直接去访问内存,把内存数据访问到,然后对内存的数据直接进行++,速度太慢;所以更愿意把这个数据从内存加载到寄存器,(因为访问寄存器很快,越往上速度越快),然后在寄存器中cpu执行这个指令(cpu中有加法器,执行完之后再把这个结果返回到内存里面),而不是去访问内存。

cpu通常是不会直接去访问内存,如果去访问内存的数据,内存的数据比较小,通常就会加载到寄存器。

这里的小指的是4/8个字节。

如果比较大就会加载到缓存(三级缓存),一级一级加载。


假设我们要执行一段指令,要访问顺序表和链表里的一段数据,例如:1 2 3 4 

在这里这些数据分别是怎么访问的呢?

我们知道,不管是顺序表还是链表,这些数据都是在内存中(堆上)的。

假设我们要执行顺序表或链表 +1 -1 等类似操作,cpu是不会直接去访问这个内存的,而是加载到缓存去访问。

加载到缓存的原因:

因为这些数据1 2 3 4 太大,所以它们不会加载到寄存器中,而是加载到缓存当中。

假设我们要访问1 2 3 4 这一段数据,cpu就会查看首元素的地址在不在缓存

  • 如果在缓存,就叫缓存命中,可以直接去访问
  • 如果不在缓存,就叫不命中,数据会先从内存加载到缓存,再访问。

那到底是怎么加载到缓存呢?

在实际加载过程中,cpu每次不会只加载一个字或一个字节,而是一块块地加载(原因:局部性原理),它会认为当前位置的数据被访问了,那与之相邻地址的数据有很大概率也会被访问

打个比方:

每个班里应该都发生过这种情况,我们正在上课。

这时候班主任突然进来说:5号你们这一列出来去把新书搬到班里。

到了楼下,班主任发现运了一车书,心想:这3个学生去搬不得累坏了。于是又到班里点了一列学生:4号这一列也出来一下。

我们发现:当班主任把5号这列叫走的时候,再去叫的时候最大可能就是叫4号这列,也就是和他们相邻的那一列。如果班主任叫人的时候,东叫一个,西叫一个,那班里不得乱糟糟的,任课老师怎么讲课啊!


那到底是加载多少字节到缓存呢?

一般是几十个字节,甚至是多少k,缓存会按照它的定义去拉取多少,它跟cpu的型号有关,叫作CPU的字长

其实读这些数据就是探测这些二进制位是0还是1,把这个01通过电信号位读到了以后然后拿过来,它是有很多很多的线连接着,cpu访问一次,有多少根线,就是访问了多少个比特位。


❥ 顺序表缓存命中率

假设最开始去访问这些数据,这些数据是都没有被访问过的,也就在缓存中,那第一个数据就是不命中。

如果是数组的话,由于第一个数据不命中,会把首地址开始的一长段数据都加载到缓存中去,如果再访问第2个位置的数据,则在缓存,也就是缓存命中。

如果数据特别长,第一个不命中,然后后面连续一长段都命中,再不命中,然后再加载到缓存,后面一长段命中......以此类推。

这就叫做:缓存利用率高(缓存命中率高)。

❥ 链表缓存命中率

那链表为什么缓存利用率低呢?

我们知道,数组在内存中是连续存放的,而链表节点与节点之间的内存不一定连续,因为每次malloc的地址都是随机的。

第一次访问的时候,我们把第一个数据后面一连串连续的地址加载到缓存,虽然有可能会访问到后面的节点,但通常情况下是访问不到的,最坏的情况是后面的一个节点都没访问到,这就会造成:缓存利用率低(缓存命中率低)。

除了不命中之外,还会导致缓存污染。

缓存污染意思是:缓存空间大小是一定的,加载进来却没有用的数据把其它数据挤走,这就造成了缓存污染。

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

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

相关文章

【十二】图解 Spring 核心数据结构:BeanDefinition

图解 Spring 核心数据结构:BeanDefinition 简介 使用spring框架的技术人员都知道spring两个大核心技术IOC和AOP,随着投入更多的时间去学习spring生态,越发觉得spring的发展不可思议,一直都是引领着Java EE的技术变革,这…

MySQL之可扩展性(一)

可扩展性 概述 有些应用仅仅适用于一台或少数几台服务器,那么哪些可扩展性建议是和这些应用相关的呢?大多数人从不会维护超大规模的系统,并且通常也无法效仿在主流大公司所使用的策略。选择一个合适的策略能够大大地节约时间和金钱。 MySQL…

ONLYOFFICE 桌面编辑器8.1---一个高效且强大的办公软件

软件介绍 ONLYOFFICE 桌面编辑器经过不断的更新换代现在迎来了,功能更加强大的ONLYOFFICE 桌面编辑器8.1是一个功能强大的办公套件,专为多平台设计,包括Windows、Linux和macOS。它提供了一套全面的办公工具,包括文档处理、电子表…

IO-Iink事件

IO-LINK事件功能 IO-Link的事件功能是其通信协议中的一项重要特性,主要用于传输设备的故障信息和维护信息。IO-Link支持三种数据类型:过程数据、参数数据和事件数据。其中,事件数据就是用于此目的。 当IO-Link设备(如传感器或执…

大咖共话|智领未来,数字化革新生命健康产业

在数字化浪潮席卷全球的今天,生命健康产业正迎来前所未有的发展机遇。6月20日,“第三届滨海中关村协同创新发展交流会”在北京隆重举办,唯迈医疗与业界大咖齐聚一堂,在“数字化赋能驱动生命健康产业发展”圆桌论坛上,共…

记一下 Stream 流操作

Java Stream流 创建流 Collection.stream() / Collection.parallelStream()&#xff1a;从集合生成流&#xff0c;后者为并行流。 List<String> list new ArrayList<>(); Stream<String> stream list.stream(); //获取一个顺序流 Stream<String> …

《C++ Primer》导学系列:第 8 章 - IO库

8.1 IO类 C标准库提供了一套丰富的输入输出&#xff08;IO&#xff09;类&#xff0c;用于处理数据的输入输出操作。这些类位于<iostream>头文件中&#xff0c;包括处理标准输入输出的istream和ostream类&#xff0c;处理文件输入输出的ifstream和ofstream类&#xff0c…

Java 8 Date and Time API

Java 8引入了新的日期和时间API&#xff0c;位于java.time包下&#xff0c;旨在替代旧的java.util.Date和java.util.Calendar类。新API更为简洁&#xff0c;易于使用&#xff0c;并且与Joda-Time库的一些理念相吻合。以下是Java 8 Date and Time API中几个核心类的简要概述&…

构建开源多模态RAG系统

在这个新的冒险中&#xff0c;我们将深入研究使用开源大型语言多模态&#xff08;LLMM&#xff09;构建检索增强型生成&#xff08;RAG&#xff09;系统的过程。值得注意的是&#xff0c;我们的重点是在不依赖LangChain或Llama索引的情况下实现这一点&#xff1b;相反&#xff…

Trilium windows上修改笔记目录,创建多个笔记空间方法

一开始使用trilium会非常的不舒服&#xff0c;不像是obsidian可以创建多个笔记空间&#xff0c;指定多个笔记目录。这里摸索到了解决方案 修改目录的方法一 ——修改系统环境变量 打开控制面板-系统-高级系统设置 新增如上条目 修改目录的方法二——直接写bat脚本运行 新建位…

Scope XY Project的使用

1.Scope XY Project的功能介绍与使用方法 添加监控变量 绘制成一个三角形 XY进行对调操作 修改XY轴的比例修改显示输出 2.Cursor的使用方法 游标线的添加测量 3.Reporting功能的使用方法 到处对应的报表数据 添加对应的报告数据

React Suspense的原理

React Suspense组件的作用是当组件未完成加载时&#xff0c;显示 fallback 组件。那么 Suspense 是如何实现的呢&#xff1f;React 的渲染是通过 Fiber 进行的&#xff0c;Suspense 的更新机制也是要围绕 Fiber 架构进行的。Suspense 是由两部分组成&#xff0c;实际 UI 子组件…

Go 语言学习笔记之字典 Map

Go 语言中的字典 Map 大家好&#xff0c;我是码农先森。 概念 在 Go 语言中&#xff0c;字典被称为 map&#xff0c;它是一种无序的集合&#xff0c;用于存储键值对。每个键在 map 中必须是唯一的&#xff0c;并且对应一个值。map 是一种非常常用的数据结构&#xff0c;用于…

iptables(6)扩展匹配条件--tcp-flags、icmp

简介 前面我们已经介绍了不少的扩展模块,例如multiport、iprange、string、time、connlimit模块,但是在tcp扩展模块中只介绍了tcp扩展模块中的”--sport”与--dport”选项,并没有介绍”--tcp-flags”选项,那么这篇文章,我们就来认识一下tcp扩展模块中的”--tcp-flags”和i…

毫米波移动通信系统中的波束赋形— 基于码本的波束训练

基于码本的波束训练算法该方法在收发端都配置波束矢量的码本&#xff0c;通过波束搜索的方式发现最优的波束方向为了加快波束搜索的速度&#xff0c;往往采用逐步缩小搜索范围的方式加快搜索&#xff0c;可以将搜索算法的时间复杂度从O(N)降低到O(logN)&#xff0c;其中N表示码…

spring-gateway include-expression 配置说明

在开发过程中遇到的一些配置问题&#xff0c;记录下来以供参考 spring-gateway版本是2.2.9-release,使用的spring cloud dependence 是 Hoxton.SR12 在依赖eureka 服务发现并自动将发现服务器加入到router中的时候&#xff0c;需要指定对应的服务进行添加&#xff0c;根据文档…

NtripShare2024年第二季度主要技术进展

NtripShare Cloud GNSS解算云平台方面 1、解算引擎增加根据卫星多路径效应自动剔除卫星的算法。 2、解算引擎增加解算时间段限制&#xff08;发现贵州某地在晚12点周期性效果变差&#xff09;。 3、增加2000坐标至地方坐标系转换的支持(七参数、四参数、TGO高程拟合&#x…

GitHub星标破千!斯坦福大学的284个机器学习小抄(漫画中文版)

说到人工智能必然要了解机器学习&#xff0c;从信息化软件&#xff0c;到电子商务&#xff0c;然后到高速发展互联网时代&#xff0c;到至今的云计算、大数据等&#xff0c;渗透到我们的生活、工作之中&#xff0c;在互联网的驱动下&#xff0c;人们更清晰的认识和使用数据&…

第一百二十三节 Java面向对象的设计 - Java接口继承

Java面向对象的设计 - Java接口继承 接口可以从另一个接口继承。与类不同&#xff0c;接口可以从多个接口继承。 interface Singer {void sing();void setRate(double rate);double getRate(); } interface Writer {void write();void setRate(double rate);double getRate();…

【代码随想录刷题】day02——977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II

977.有序数组的平方 方法一&#xff1a;暴力法 class Solution { public:vector<int> sortedSquares(vector<int>& nums) {// 暴力法for(int i 0; i < nums.size(); i){nums[i] * nums[i];}sort(nums.begin(), nums.end());return nums;} };方法二&#…