JavaScript:CPU缓存预取以及确定数据下直接更改数组length的好处

news/2025/2/11 9:41:50/

CPU缓存预取以及确定数据下直接更改数组length的好处

  • 1. CPU 缓存预取(Cache Preloading):
    • CPU 缓存预取:
    • 为什么反向填充栈能利用缓存预取:
  • 2. 为什么可以直接改变数组的 length:
    • 数组的动态长度:
      • 为什么可以直接改变 length:
    • 性能考虑:
  • 总结:

1. CPU 缓存预取(Cache Preloading):

在这段代码中,findFSTNodeByDataName 使用了一个 stack 数组来存储待处理的节点,并且通过反向填充栈来优化性能,特别是在 CPU 缓存的使用上。

const stack = new Array(payload.length);
let stackIdx = payload.length;// 反向填充初始栈(利用 CPU 缓存预取)
for (let i = 0; i < payload.length; i++) {stack[i] = payload[i];
}

CPU 缓存预取:

  • 在现代计算机中,CPU 会使用缓存(例如 L1/L2 缓存)来提高内存访问速度。访问较远的内存地址(比如跨越不同缓存块的数据)可能会导致较慢的访问速度。为了提高效率,CPU 会预取(预加载)一些内存块,提前将它们加载到缓存中,以减少等待时间。

为什么反向填充栈能利用缓存预取:

  • 由于 stack[i] = payload[i] 是顺序访问数组的元素,而数组通常是按顺序存储在内存中的(尤其是在大数组或一维数组中)。访问内存时,CPU 会预取接下来的内存区域,因为数组的内存是线性分布的。因此,在这个循环中,填充栈的过程本身会触发CPU预取操作,使得数据在栈上被预加载,后续的栈操作就能更高效地访问这些数据。
  • 更进一步,现代 JavaScript 引擎和操作系统会在物理内存中对数据进行布局优化,使得连续的内存区域更有可能被缓存(如数组元素连续存储在内存中)。通过反向填充(从栈顶往下填充),代码可能更好地利用了 CPU 的预取机制,提高了内存访问的效率。

2. 为什么可以直接改变数组的 length:

在这段代码中,当栈中某个节点有子节点时,代码改变了 stack 数组的 length:

const children = node.children;
if (children?.length) {const childLen = children.length;stack.length = stackIdx + childLen;  // 改变数组长度for (let j = 0; j < childLen; j++) {stack[stackIdx + j] = children[j];}stackIdx += childLen;
}

数组的动态长度:

  • 在 JavaScript 中,数组的 length 是一个动态属性,你可以随时通过设置 length 来扩展或收缩数组。当你设置 stack.length = stackIdx + childLen 时,实际上是调整了数组的大小,使它容纳更多的元素。需要注意的是,改变数组 length 只会影响已分配的数组内存(对于扩展数组会重新分配内存)。

为什么可以直接改变 length:

  • JavaScript 数组是动态的,它们可以按需增加或缩小。虽然 length 是一个特殊的属性,但它与数组的元素存储是分开的。这使得在访问数组元素时,设置 length 会自动调整数组的大小,且这种操作不需要手动分配新的内存。JavaScript 引擎内部会自动管理数组内存的重新分配或收缩。
  • 在这段代码中,stack.length = stackIdx + childLen 是为了将栈的长度调整到适应当前子节点的数量。这种做法与使用 push 或 unshift 添加元素相比,性能上会更高。通过直接设置 length,数组的内存布局会被调整,以便为新元素腾出空间。更重要的是,length 的操作不会导致 push 的隐式内存分配和元素复制过程。

性能考虑:

  • 当你直接设置 length 时,相比 push 或 unshift,通常会避免不必要的内存重新分配和复制,尤其是在元素的数量已知或变化可控的情况下。这种方式避免了多次进行内存扩容操作,提高了性能。

总结:

1.	CPU 缓存预取:通过反向填充栈,可以利用 CPU 的预取机制,提高内存访问效率。这种方法优化了内存布局,避免了频繁的随机内存访问,提高了缓存命中率。
2.	直接改变 length 的原因:在 JavaScript 中,数组的 length 可以直接修改,它是一个动态的属性。修改 length 不需要进行数组的复制或其他操作,因此相比 push 等方法,能更高效地调整数组的大小,避免了不必要的内存分配和数据复制。

这种技术的组合方式(使用反向填充和调整数组 length)可以帮助提升性能,尤其是在处理大量数据时,减少内存分配和复制的开销,进而提高算法效率。


http://www.ppmy.cn/news/1571125.html

相关文章

深度优先搜索(DFS)——八皇后问题与全排列问题

&#xff08; ^ _ ^ &#xff09; 数据结构好难哇&#xff08;哭 1.BFS和DFS 数据结构空间性质DFSstackO(h)不具有最短性质BFSqueueO(2^h)具有最短路性质 空间上DFS占优势&#xff0c;但是BFS具有最短性 &#xff08;若所有权重都是1&#xff0c;则BFS一定最短&#xff09;&…

科技资讯杂志科技资讯杂志社科技资讯编辑部2024年第24期目录

学思践悟二十大 “枫桥经验”的思想政治教育内涵及启示——践行党的二十大精神 洪希彦; 1-330 构建符合党的二十大精神的高职院校劳动教育课程体系研究 李曼; 4-7 党的二十大精神引领下“隧道施工”课程思政探究 张志明;陈国辉; 8-10 新质生产力 新质生产力视域…

Pdf手册阅读(1)--数字签名篇

原文阅读摘要 PDF支持的数字签名&#xff0c; 不仅仅是公私钥签名&#xff0c;还可以是指纹、手写、虹膜等生物识别签名。PDF签名的计算方式&#xff0c;可以基于字节范围进行计算&#xff0c;也可以基于Pdf 对象&#xff08;pdf object&#xff09;进行计算。 PDF文件可能包…

【详细版】DETR系列之Deformable DETR(2021 ICLR)

论文标题Deformable DETR: Deformable Transformers for End-to-End Object Detection论文作者Xizhou Zhu, Weijie Su, Lewei Lu, Bin Li, Xiaogang Wang, Jifeng Dai发表日期2021年03月01日GB引用> Xizhou Zhu, Weijie Su, Lewei Lu, et al. Deformable DETR: Deformable T…

elementplus 使用日期时间选择器,设置可选范围为前后大于2年且只能选择历史时间不能大于当前时间点

需求&#xff1a;时间选择器可选的时间范围进行限制&#xff0c;-2年<a<2年且a<new Date().getTime()核心&#xff1a;这里需要注意plus版没有picker-options换成disabled-date属性了&#xff0c;使用了visible-change和calendar-change属性逻辑&#xff1a;另设一个参…

保姆级教程Docker部署Zookeeper模式的Kafka镜像

目录 一、安装Docker及可视化工具 二、Docker部署Zookeeper 三、单节点部署 1、创建挂载目录 2、命令运行容器 3、Compose运行容器 4、查看运行状态 5、验证功能 四、部署可视化工具 1、创建挂载目录 2、Compose运行容器 3、查看运行状态 一、安装Docker及可视化工…

相机开启状态下拔出SD卡导致的数据丢失问题及恢复方法

在使用数码相机拍摄照片或视频时&#xff0c;我们偶尔会遇到急需查看已拍摄内容或者管理存储空间的情况。有时&#xff0c;在未关闭相机电源的情况下&#xff0c;用户可能会尝试直接拉出SD卡&#xff0c;这种操作极有可能导致数据丢失甚至损坏SD卡。本文将详细探讨这一现象&…

前端导出pdf,所见即所得

一、推荐方案&#xff1a;html2canvas jsPDF&#xff08;图片式PDF&#xff09; javascript import html2canvas from html2canvas; import jsPDF from jspdf;const exportPDF async (elementId, fileName) > {const element document.getElementById(elementId);// 1.…