文章目錄
- 前言
- 一、語法對比
- 1. `Array.prototype.concat()`
- 2. 擴展運算符(解構賦值)
- 二、性能差異(大規模數組)
- 關鍵差異原因
- 三、適用場景建議
- 總結
前言
最近工作中遇到了一個大規模數組合并相關的問題,在數據合并時有些耗時嚴重,這里記錄一下,這里探究一下concat()
和擴展運算符的差異。
一、語法對比
1. Array.prototype.concat()
直接創建一個新數組,按順序復制所有元素。內存分配是單次連續操作,引擎可一次性預分配內存。
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const merged = arr1.concat(arr2); // [1, 2, 3, 4, 5, 6]
2. 擴展運算符(解構賦值)
需要多次動態擴容:初始為空數組,逐步添加元素時可能觸發多次內存重分配(類似 push())。
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const merged = [...arr1, ...arr2]; // [1, 2, 3, 4, 5, 6]
// 擴展運算符執行類似于以下:
// const merged = [];
// for (const item of arr1) merged.push(item);
// for (const item of arr2) merged.push(item);
二、性能差異(大規模數組)
指標 | concat() | 解構賦值 [...arr] |
---|---|---|
時間復雜度 | O(n)(單次連續復制) | O(n)(但含多次擴容開銷) |
實際速度 | 更快(引擎高度優化) | 較慢(尤其數組極大時) |
內存峰值 | 較低(預分配連續內存) | 較高(擴容時舊新數組同時存在) |
10 萬元素耗時示例 | ~5ms | ~15ms(慢 2-3 倍) |
100 萬元素耗時示例 | ~50ms | ~200ms(慢 4 倍以上) |
關鍵差異原因
-
擴容成本:
解構賦值的動態push()
行為在數組極大時可能觸發多次內存擴容(如容量 2→4→8→16…),每次擴容需復制舊數據到新內存區域。 -
引擎優化:
concat()
被 JavaScript 引擎(如 V8)深度優化,可直接操作內存塊,避免中間步驟。 -
臨時迭代器:
解構賦值需要為每個數組創建迭代器對象,增加額外開銷。
三、適用場景建議
場景 | 推薦方法 | 原因 |
---|---|---|
數組合并(> 10,000 元素) | concat() | 性能優勢顯著,內存占用低 |
小型數組(< 1000 元素) | 解構賦值 | 代碼簡潔,差異可忽略 |
需動態插入元素 | 解構賦值 | 方便添加額外元素([...a, x, ...b] ) |
內存敏感環境(如低端設備) | concat() | 避免多次擴容導致的內存峰值 |
總結
-
大型數組(> 10k 元素):優先用 concat()(不修改原數組)或 push(…arr)(可修改原數組)。
-
解構賦值 […arr1, …arr2]:僅推薦小型數組或需要代碼簡潔的場景。
-
性能排序(大數組合并):
push(…arr) > concat() > […arr1, …arr2]