求可在2秒内完成1到n(n≤10^8)数组填充的高效算法
JavaScript 生成1~n大数组性能优化方案
原代码性能瓶颈原因
你原有实现的耗时过高核心原因是普通JS数组的动态扩容开销:默认[]声明的空数组初始容量很小,每次调用push当容量不足时,JS引擎会申请新的更大的内存空间、拷贝原有数组全部元素到新空间,1e8量级的元素会触发几十次扩容,拷贝开销占了总耗时的90%以上。
可行优化方案
方案1:预分配普通数组长度(适合需要普通Array类型的场景)
提前声明固定长度的数组,完全避免动态扩容开销,性能比原实现提升4~6倍:
const n = 100000000; const arr = new Array(n); // 预分配对应长度的内存空间 for (let i = 0; i < n; i++) { arr[i] = i + 1; } console.log(arr);
注意:不要使用Array.from、map等带回调的高阶函数生成大数组,回调的单次调用开销在1e8量级下会被放大,性能远低于原生for循环。
方案2:使用类型化数组(性能最优,符合2秒时限要求)
如果对数组类型没有特殊要求,优先使用Uint32Array等类型化数组,它的内存是连续分配的、没有JS动态类型的额外开销,写入速度是普通数组的34倍,V8引擎下1e8元素的生成耗时可以控制在1.51.8秒:
const n = 100000000; // Uint32Array支持的最大元素值为4294967295,远大于1e8,完全适配需求 const arr = new Uint32Array(n); for (let i = 0; i < n; i++) { arr[i] = i + 1; } console.log(arr);
1e8个Uint32元素的内存占用为400MB左右,属于正常内存开销,不会触发内存溢出。
字符串生成场景优化
如果需要生成拼接好的字符串,不要做循环字符串拼接,先通过类型化数组生成数值集合,再调用一次join方法批量拼接即可,性能比循环拼接高10倍以上:
const n = 100000000; const arr = new Uint32Array(n); for (let i = 0; i < n; i++) arr[i] = i + 1; const resultStr = arr.join(','); // 按需求调整分隔符即可
内容的提问来源于stack exchange,提问作者nqx1
相关产品推荐
相关产品推荐

