Nodejs 中forEach与for的性能对比,谁快谁慢?

Nodejs 中forEach与for的性能对比,谁快谁慢?

在对数组的遍历中,我在多处查到forEach差for的速度太大了,但是我自己试着测试时,结果却是相反的~

d0c8a786c9177f3e04e69edc72cf3bc79e3d5614.jpg

这是在 http://jsperf.com/fast-array-foreach 的在线运行结果,很明显能看出来forEach很慢

但是我在chrome控制台中再次运行时 1e30e924b899a9018f6236e71f950a7b0308f588.jpg

却得到了这样的结果,有点疑惑,希望大家能解释下


10 回复

Node.js 中 forEachfor 的性能对比,谁快谁慢?

在 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 版本),这两种方法的性能表现可能会有所不同。根据你在问题中提到的结果,你可以看到:

  1. 在某些在线测试工具(如 jsPerf)中,forEach 确实比 for 循环慢。
  2. 但在 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中,forEachfor 循环的性能差异可能会因为不同的运行环境和实现细节而有所不同。通常情况下,直接使用 for 循环可能比 forEach 更快,因为 forEach 需要处理回调函数的调用以及一些额外的上下文切换。不过,在某些环境中,这种差距可能并不明显。

示例代码

以下是一些示例代码,可以用来测试 forEachfor 循环在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万个元素的数组,并分别使用 forforEach 循环进行迭代。通过 console.timeconsole.timeEnd 来测量两种方法的时间消耗。

可能的解释

  • 环境差异:在不同的Node.js版本或不同的JavaScript引擎(如V8)中,forEachfor 的性能表现可能会不同。
  • 回调函数的开销forEach 需要调用回调函数,这会带来额外的开销。如果你的回调函数非常简单,这种开销可能会变得不那么显著。
  • 优化:现代JavaScript引擎有很多优化机制,例如内联缓存、JIT编译等,这些机制可能会让某些循环的表现更加接近。

希望这些信息对你有所帮助!

回到顶部