Nodejs 中forEach与for的性能对比,谁快谁慢?
Nodejs 中forEach与for的性能对比,谁快谁慢?
在对数组的遍历中,我在多处查到forEach差for的速度太大了,但是我自己试着测试时,结果却是相反的~
这是在 http://jsperf.com/fast-array-foreach 的在线运行结果,很明显能看出来forEach很慢
但是我在chrome控制台中再次运行时
却得到了这样的结果,有点疑惑,希望大家能解释下
Node.js 中 forEach
与 for
的性能对比,谁快谁慢?
在 Node.js 中,对于数组的遍历,我们经常需要选择合适的循环方式。常见的两种方法是使用 forEach
和传统的 for
循环。那么,它们的性能表现如何呢?让我们通过一些简单的示例代码来探讨一下。
示例代码
首先,我们来看一个简单的示例代码,用于遍历一个包含大量元素的数组,并计算每个元素的平方值。
const array = Array.from({ length: 1000000 }, (_, i) => i);
// 使用 for 循环
function usingFor() {
const result = [];
for (let i = 0; i < array.length; i++) {
result.push(array[i] * array[i]);
}
return result;
}
// 使用 forEach 方法
function usingForEach() {
const result = [];
array.forEach(item => {
result.push(item * item);
});
return result;
}
性能测试
接下来,我们可以使用 performance.now()
来测量这两种方法的执行时间。
const start = performance.now();
usingFor();
const end = performance.now();
console.log(`Using For: ${end - start} ms`);
const start2 = performance.now();
usingForEach();
const end2 = performance.now();
console.log(`Using ForEach: ${end2 - start2} ms`);
结果分析
在不同的环境中(例如不同的浏览器或 Node.js 版本),这两种方法的性能表现可能会有所不同。根据你在问题中提到的结果,你可以看到:
- 在某些在线测试工具(如 jsPerf)中,
forEach
确实比for
循环慢。 - 但在 Chrome 控制台中,你观察到了相反的结果。
这可能是由于以下几个原因:
- 环境差异:不同的测试工具和环境可能会影响性能测试的结果。
- JavaScript 引擎优化:现代 JavaScript 引擎(如 V8)会对某些代码进行优化,从而导致不同方法之间的性能差异。
- 具体实现细节:
forEach
方法在内部实现上可能包含了额外的开销,如函数调用和上下文切换。
结论
总的来说,虽然 for
循环在某些情况下确实比 forEach
快,但这并不是绝对的。具体的表现会受到多种因素的影响。如果你需要在性能敏感的场景中进行大量的数组遍历操作,建议先进行实际的性能测试,以确定最适合你特定情况的方法。
希望这些信息对你有所帮助!
图片无法查看
经过再次测试,这与浏览器控制台的工作环境和模式有关。 在控制台下,for的工作时间变长,才造成了上面的误会。
for 要快很多
forEach 会创建一个新的作用域(匿名函数),主要开销在这里
var l = [];
for (var i = 0; i < 1000000; i++) {
l.push(i);
}
var a = Date.now();
for (var i = 0, len = l.length; i < len; i++) {
(function f(item) {}());
}
var b = Date.now();
console.log('for: ', b - a);
var a = Date.now();
l.forEach(function (item) {});
var b = Date.now();
console.log('forEach: ', b - a);
自己写的东西最可信
在浏览器中执行和在node中性能差异是否不同?
我自己也试过,结果毋庸置疑 for要比forEach要快很多,我想问下什么情况下用forEach比较好呢,有没有经典的例子什么的。
查看 V8 源码 https://github.com/v8/v8/blob/master/src/js/array.js#L1037-L1055
function InnerArrayForEach(f, receiver, array, length) {
if (!IS_CALLABLE(f)) throw %make_type_error(kCalledNonCallable, f);
if (IS_UNDEFINED(receiver)) {
for (var i = 0; i < length; i++) {
if (i in array) {
var element = array[i];
f(element, i, array);
}
}
} else {
for (var i = 0; i < length; i++) {
if (i in array) {
var element = array[i];
%_Call(f, receiver, element, i, array);
}
}
}
}
每次调用都有 2 个判断,一个是参数是否为函数,另一个是元素是否为 undefined。
在Node.js中,forEach
和 for
循环的性能差异可能会因为不同的运行环境和实现细节而有所不同。通常情况下,直接使用 for
循环可能比 forEach
更快,因为 forEach
需要处理回调函数的调用以及一些额外的上下文切换。不过,在某些环境中,这种差距可能并不明显。
示例代码
以下是一些示例代码,可以用来测试 forEach
和 for
循环在Node.js中的性能:
const array = Array.from({length: 1000000}, (_, i) => i);
// 使用 for 循环
function testForLoop() {
let sum = 0;
for (let i = 0; i < array.length; i++) {
sum += array[i];
}
}
// 使用 forEach
function testForEachLoop() {
let sum = 0;
array.forEach(item => {
sum += item;
});
}
console.time('For Loop');
testForLoop();
console.timeEnd('For Loop');
console.time('ForEach Loop');
testForEachLoop();
console.timeEnd('ForEach Loop');
解释
上述代码创建了一个包含100万个元素的数组,并分别使用 for
和 forEach
循环进行迭代。通过 console.time
和 console.timeEnd
来测量两种方法的时间消耗。
可能的解释
- 环境差异:在不同的Node.js版本或不同的JavaScript引擎(如V8)中,
forEach
和for
的性能表现可能会不同。 - 回调函数的开销:
forEach
需要调用回调函数,这会带来额外的开销。如果你的回调函数非常简单,这种开销可能会变得不那么显著。 - 优化:现代JavaScript引擎有很多优化机制,例如内联缓存、JIT编译等,这些机制可能会让某些循环的表现更加接近。
希望这些信息对你有所帮助!