当前位置: 首页 > news >正文

【数据结构】顺序表与链表的差异

顺序表和链表都是线性表,它们有着相似的部分,但是同时也有着很大的差异。

 存储空间上的差异:

对于插入上的不同点,顺序表在空间不够时需要扩容,而如果在使用realloc函数去扩容,会有原地扩容和异地扩容两种情况,若申请的空间没有被使用,则会用原地扩容,消耗不会大。但是若申请被使用的话,则会用异地扩容,则会在堆区上申请一块空间,并把原来的数据拷贝过来,就会造成消耗会比较大的问题。而带头双向循环链表则不需要考虑到这些问题,只需要按需申请释放就可以了。同时,顺序表的扩容还可能存在空间浪费的问题。

关于原地扩容和异地扩容的代码:

int main()
{int* p1 = (int*)malloc(8);printf("%p\n", p1);int p2 = (int*)realloc(p1, 800);printf("%p\n", p2);return 0;
}

原地扩容:

异地扩容

 

关于缓存利用率两种线性表也有很大的不同。

在此之前,我们首先要知道缓存(高速缓冲存储器)是什么?

在多体并行存储系统中,由于I/O设备向主存请求的级别高于CPU访存,这就出现了CPU 等待I/0设备访存的现象,致使CPU空等一段时间,甚至可能等待几个主存周期,从而降低了CPU的工作效率。为了避免CPU与I/O设备争抢访存,可在CPU与主存之间加一级缓存(参见图4.3),这样,主存可将CPU要取的信息提前送至缓存,一旦主存在与I/O设备交换时,CPU 可直接从缓存中读取所需信息,不必空等而影响效率。 

从另一角度来看,主存速度的提高始终跟不上CPU的发展。据统计,CPU的速度平均每年改进60%,而组成主存的动态RAM速度平均每年只改进7%,结果是CPU和动态RAM之间的速度间隙平均每年增大50%。例如,100MHz的Pentium处理器平均每10ns就执行一条指令,而动态RAM的典型访问时间为60~120ns。这也希望由高速缓存Cache 来解决主存与CPU速度的不匹配问题。

缓存的命中:

在说明这两个问题之前。我们需要要解一个术语 Cache Line。缓存基本上来说就是把后面的数据加载到离自己近的地方,对于CPU来说,它是不会一个字节一个字节的加载的,因为这非常没有效率,一般来说都是要一块一块的加载的,对于这样的一块一块的数据单位,术语叫“Cache Line”,

比如:Cache Line是最小单位(64Bytes),所以先把Cache分布多个Cache Line,比如:L1有32KB,那么,32KB/64B = 512 个 Cache Line。

在计算机读取数据的时候,计算机会根据地址去访问,如果数据在缓存上,则称为命中成功,直接就可以访问数据了。如果数据在主存上,则称为命中失败,就需要将主存上的数据移到缓存上,这时就需要使用Cache来进行运输。

我们再与线性表联系起来。

顺序表的物理结构和逻辑结构的方面上都是连续的,在数据在主存上的情况下,数据被移到cache上面。同时,因为对于CPU来说,它一般来说都是要一块一块的加载的,也就代表着加载的时候会将顺序表连带着后面的数据一并加载到cache上面,也就节省了时间,节约了空间,提高了程序的运行效率。

链表(双向带头循环链表)的逻辑结构是不连续的,但是它的物理结构却是不连续的。所以,在CPU一块一块加载数据的时候,在加载第一个数据的时候并不会连带着后面的数据去加载(参考下图),也就降低了程序运行的效率。同时,因为有大量的无用的数据加载到缓存,会造成数据的污染,影响程序的性能。

想对缓存的命中有更深的了解的话,可以参考陈皓大佬的文章《程序员相关的CPU缓存知识 》进一步了解。

与程序员相关的CPU缓存知识 | 酷 壳 - CoolShell

http://www.lryc.cn/news/346293.html

相关文章:

  • 小程序如何进行评分评价
  • 【MATLAB源码-第206期】基于matlab的差分进化算法(DE)机器人栅格路径规划,输出做短路径图和适应度曲线。
  • Python图形界面(GUI)Tkinter笔记(三):控件的定位(1)
  • 数据结构--单链表 详解(附代码
  • leetcode 1749.任意子数组和的绝对值的最大值
  • Linux进程——进程地址空间
  • 基于 LlaMA 3 + LangGraph 在windows本地部署大模型 (三)
  • python3如何安装bs4
  • docker容器技术篇:rancher管理平台部署kubernetes集群
  • 【计算机网络原理】初识网络原理和一些名词解释​​
  • 车载电子电器架构 —— 关于bus off汇总
  • Linux函数
  • 如何查看centos7中Java在哪些路径下
  • 信息安全-古典密码学简介
  • 面试题 01.05. 一次编辑
  • 针对头疼的UDP攻击如何定制有效的防护措施
  • 怎么制作流程图?介绍制作方法
  • 棱镜七彩参编《网络安全技术 软件供应链安全要求》国家标准发布
  • Keepalived实现LVS高可用
  • 【力扣】1089.复写零
  • Golang实践录:gin框架使用自定义日志模块
  • Django之配置数据库
  • Ajax 笔记02
  • 【隧道篇 / WAN优化】(7.4) ❀ 03. WAN优化的原理 ❀ FortiGate 防火墙
  • 网络爬虫概述与原理
  • 可视化实验三 Matplotlib库绘图及时变数据可视化
  • 开启多线程下变量共享与私有问题
  • Qt模型视图代理之QTableView应用的简单介绍
  • 第七届精武杯部分wp
  • 3.2Java全栈开发前端+后端(全栈工程师进阶之路)-前端框架VUE3框架-企业级应用- Vuex