• 作者:老汪软件技巧
  • 发表时间:2024-09-20 00:02
  • 浏览量:

基础概念普及稀疏数组

稀疏数组其实指的就是那些数据在内存中不连续的数组,即数组的长度大于元素的个数。

在JavaScript中,创建有长度的数组时,会看到Empty,当创建数组后,没有给具体内容时,就会展示Empty对位置进行占位。

当这个Empty出现在某个部分赋值的数组中间时,这便可以称其为空隙。

而稀疏数组就是存在空隙的数组。稀疏矩阵中Empty,描述的是一个空对象的引用。它可以等于undefined,但JS的一些API则是对它有不同的行为处理,如:

密集数组

密集数组则是元素中不存在空隙的数组。

直接生成密集数组:

const arr1 = [...new Array(1024)];//[undefined, undefined ...]
const arr2 = Array.apply(null, new Array(1024));//[undefined, undefined ...]
const arr3 = Array.from(new Array(1024))//[undefined, undefined ...]

快数组

在JavaScript中快数组其实就是在内存中开辟一片连续的内存区域用来存储数据,这种连续的内存在数组便利时,遍历效率会高很多,但同时由于快数组内存是连续的,因此可能需要开辟一大块内存供其使用,其中很有可能会开辟一块完整的大内存,其中很有可能没有完全使用到,从而可能出现内存浪费的情况。

关键词:内存是连续的``遍历效率高``内存浪费

创建快数组的方式

当初始化时,可以直接初始化固定长度的密集数组,这时就会创建快数组:

const LENGTH = 1024 * 1024 * 5;
const arr = new Array(LENGTH);
for(let i = 0; i < LENGTH; i++) arr[i] = i;
// 这时的arr就是快数组

数组底层实现原理__数组的底层

看到这里时,可能会问:“如果我不连续的插入值时,创建的是什么数组? ”

这里就要考虑插入时,数组的稀疏程度了,如果稀疏的程度不高时,我们创建的依旧是快数组:

const LENGTH = 1024 * 1024 * 5;
const arr = new Array(LENGTH);
// 这里只会在偶数下标的位置插入值
for(let i = 0;i < LENGTH; i+=2) arr[i] = i;
// 这里依旧是快数组

有的人看到这里,可能还会有疑问:“如果我插入不同类型的数据,那么数组这时是不是就是慢数组了呢? ”

其实不然,在JavaScript中,数组的类型不会影响数组的性质,当我们创建了快数组后,即使插入了不同类型的数据也不会影响其性质。

const LENGTH = 1024 * 1024 * 5;
const arr = new Array(LENGTH);
for(let i = 0;i < LENGTH; i++){
  switch(i){
    case i % 5:{
      arr[i] = true;
      break;
    }
    case i % 2:{
      arr[i] = i;
      break
    }
    default:{
      arr[i] = `${i}`;
      break;
    }
  }
}
// 这里依旧是快数组

慢数组

而在JavaScript中慢数组,则是使用了HashTable的数据结构,它类似于一种对象的结构,只不过对象的索引是数字【而数字作为索引key时会被强制转换为字符串】,并且其对应的数据分配的内存非常零散,其好处是可以节省内存,但是遍历效率却会慢上许多;。

关键词:内存是分散的 节省内存 遍历效率低

快慢数组转换快数组转慢数组

一般快数组转慢数组一般都是因为数组扩容原因:

在快数组扩容时,新容量大于当前容量一定倍数时【即当前容量的 3 * 3倍时】,快数组将会转变为慢数组。当新增的数据位置所在的下标减去当前快数组最大容量大于等于1024时,则会转换为慢数组。慢数组转快数组

而慢数组转为快数组的条件则是在操作数组时,当慢数组检测节省空间小于等于50%时,即使用稀疏数组节省空间并没有节省很多空间时,这时慢数组则会转为快数组。

源码

数组:/v8/v8/blob/…

数组类型转换:


上一条查看详情 +RocketMQ消息发送之延迟消息
下一条 查看详情 +没有了