gpt4 book ai didi

javascript - 如何在 Javascript 中向现有数组添加大量元素?

转载 作者:太空宇宙 更新时间:2023-11-04 15:52:11 25 4
gpt4 key购买 nike

例如,我有两个非常大的数组ab,每个数组都有数百万个元素。我想将数组 b 的所有元素附加到数组 a 中。另外,我不想创建新数组,而是更改现有数组 a (因此 concat 不是一个选项)。

我已经尝试过:

Array.prototype.push.apply(a, b)

但是对于非常大的数组,这会给我一个错误:

RangeError: Maximum call stack size exceeded

我知道我可以创建一个循环并使用 push 逐个添加元素。

有更好的方法吗?

最佳答案

根据这个问题 ( Is there a max number of arguments JavaScript functions can accept? ) 判断,一次可以安全附加的最大参数数量约为 100,000 。假设您有足够的内存一次拥有 100,000 个项目的重复列表,您可以使用下面显示的切片方法。 (参见下面详述的拼接和应用方法)

但是,我以不同的形式对各个推送方法进行了基准测试比较,以查看这样做是否有任何性能优势,因为在幕后,拼接串联可能仍然是按元素进行的,而不是批量 memcpy 操作。

const x = [];

for (let i = 0; i < 10000000; i += 1) {
x.push(i);
}

const a = x.slice();
const b = x.slice();
const v = x.slice();
const y = x.slice();
const z = x.slice();


// append 100,000 at a time using splice
const sliceStart = new Date();
for (let i = 0; i < b.length; i += 100000) {
const len = (i + 100000) % (b.length + 1);
const c = b.slice(i, len);
a.splice(a.length, 0, ...c);
}
const sliceEnd = new Date();

// append 100,000 using Array.prototype.push
const protoStart = new Date();
for (let i = 0; i < b.length; i += 100000) {
const len = (i + 100000) % (b.length + 1);
const c = b.slice(i, len);
Array.prototype.push.apply(v, c);
}
const protoEnd = new Date();

// using for and push
const pushStart = new Date();
for (let i = 0; i < b.length; i += 1) {
y.push(b[i]);
}
const pushEnd = new Date();

// using for and push
const batchPushStart = new Date();
for (let i = 0; i < b.length; i += 8) {
y.push(b[i]);
y.push(b[i + 1]);
y.push(b[i + 2]);
y.push(b[i + 3]);
y.push(b[i + 4]);
y.push(b[i + 5]);
y.push(b[i + 6]);
y.push(b[i + 7]);
}
const batchPushEnd = new Date();

// using forEach and push
const forEachStart = new Date();
b.forEach(i => z.push(i));
const forEachEnd = new Date();

console.log("Slice method:", sliceEnd - sliceStart);
console.log("Apply method:", protoEnd - protoStart);
console.log("For and push method:", pushEnd - pushStart);
console.log("For and batch push method:", batchPushEnd - batchPushStart);
console.log("Foreach and push method:", forEachEnd - forEachStart);

在 2014 MacBook Pro 15"上运行 10,000,000 个元素结果:

Slice method: 1400
Apply method: 275
For and push method: 896
For and batch push method: 409
Foreach and push method: 707

for 和 foreach 单推方法在 Chrome V8 上的性能大致相当。我发现切片方法的性能大约差 2-3 倍。

更新:Array.prototype.push.apply 添加批处理方法后,它提供了比单次推送方法更好的性能!然而,展开循环似乎有时会显着提高性能,有时则不会,具体取决于列表的大小以及在其之前或之后的其他工作...?

请注意,增加初始 x 数组的大小可能会使 Chrome 中的页面崩溃,因为它可能会超出页面/选项卡的最大内存限制。

总而言之,为了简单起见,请坚持使用常规的 array.push(..) ,但批处理的 Array.prototype.push.apply 方法可能会引起人们的兴趣。性能。

关于javascript - 如何在 Javascript 中向现有数组添加大量元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43022646/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com