知用网
柔彩主题三 · 更轻盈的阅读体验

数组性能优化技巧:让代码跑得更快的实用方法

发布时间:2025-12-17 03:43:15 阅读:495 次

避免频繁的数组扩容

在处理大量数据时,如果不断往数组里添加元素,比如用 JavaScript 的 push 方法,系统可能会反复触发内存重新分配。就像搬家时不断往纸箱里塞东西,塞满了再换更大的箱子,来回折腾很费时间。提前预估数据量,初始一个合适大小的数组能省不少事。

// 不推荐:边循环边 push,可能多次扩容
let arr = [];
for (let i = 0; i < 100000; i++) {
  arr.push(i);
}

// 推荐:预先分配长度
let arr = new Array(100000);
for (let i = 0; i < 100000; i++) {
  arr[i] = i;
}

优先使用索引访问而非高阶函数

mapfilter 这些方法写起来简洁,但每次都会创建新数组并遍历所有元素。如果只是想读取或修改数据,直接用 for 循环访问索引效率更高。

// 耗时较长
const doubled = items.map(x => x * 2);

// 更快的方式
const doubled = new Array(items.length);
for (let i = 0; i < items.length; i++) {
  doubled[i] = items[i] * 2;
}

减少嵌套循环操作

两个数组做对比查找时,很容易写出双重 for 循环。这种写法在数据量稍大时性能急剧下降。可以用对象或 Set 把查找变成常数时间,就像从杂乱抽屉翻东西变成查标签柜子,快得多。

// O(n²) 性能差
for (let i = 0; i < arr1.length; i++) {
  for (let j = 0; j < arr2.length; j++) {
    if (arr1[i] === arr2[j]) {
      // 找到了
    }
  }
}

// O(n) 优化版本
const set2 = new Set(arr2);
for (const item of arr1) {
  if (set2.has(item)) {
    // 找到了
  }
}

慎用数组拼接和切片

频繁使用 concatslice 会产生大量中间数组,占用内存。如果是合并多个数组,考虑用 push.apply 或扩展运算符配合预分配空间。

// 内存抖动大
let result = [];
for (const part of chunks) {
  result = result.concat(part);
}

// 更高效的做法
let result = [];
for (const part of chunks) {
  Array.prototype.push.apply(result, part);
}

利用缓存提升重复访问效率

如果要在循环中反复获取数组长度,别每次都调用 arr.length。虽然看起来只是个属性,但在某些环境或代理数组中可能有计算开销。把它存成变量,就像出门前看一次手表,而不是每走一步都看一眼。

for (let i = 0, len = arr.length; i < len; i++) {
  // 使用 arr[i]
}