ES6扩展元素与嵌套forEach性能



我有以下函数

const modules = [{courses:[...]},{courses:[...]},...]
const deleteCourses = [];
modules.forEach((mod) => {
mod.courses.forEach((course) => {
deleteCourses.push(course));
}
// versus
deleteCourses = [...deleteCourses, ...mod.courses];
});

假设模块和课程的长度在30-100之间,我想知道其中哪一个更有效?

一方面,我被教导要避免嵌套forEach循环。另一方面,数组文字每次都会创建一个新的Array实例。

谢谢!

似乎嵌套的forEach要快得多,正如jsPerf所示:

设置:

const modules = Array(30).fill({courses:Array(30).fill(1)}) //30x30 elements
let deleteCourses = [];

案例1:嵌套的forEach-29293 ops/sec

modules.forEach((mod) => {
mod.courses.forEach((course) => {
deleteCourses.push(course);
})
})

情况2:ES6排列运算符-49.13操作/秒

modules.forEach((mod) => {
deleteCourses = [...deleteCourses, ...mod.courses];
})

30x30样本的速度大约快600倍

当您考虑在每次迭代中重新读取deleteCourses时的冗余量时,这是有意义的。与嵌套的forEach不同,每次迭代执行的加法运算数量大约是该迭代的deleteCourses的长度。这个数字在每次迭代中都在增长。

因此,性能上的差异与创建新的Array实例没有太大关系,而与滥用扩展运算符所产生的大量冗余步骤有很大关系。

可以肯定的是,单独来看这两种情况,我们可以看到:

  • ES6 Spread Operator算法是指数型的:O(2^n)
  • 嵌套的forEach算法是线性的:O(n)

最新更新