一尘不染

For循环性能:将数组长度存储在变量中

javascript

考虑同一循环迭代的两个版本:

for (var i = 0; i < nodes.length; i++) {
    ...
}

var len = nodes.length;
for (var i = 0; i < len; i++) {
    ...
}

后一种版本比前一种版本快吗?


阅读 553

收藏
2020-05-01

共1个答案

一尘不染

更新:16/12/2015

由于这个答案似乎仍然有很多观点,我想重新审视这个问题,因为浏览器和JS引擎不断发展。

我没有使用JSPerf,而是使用原始问题中提到的两种方法,编写了一些代码来遍历数组。我已将代码放入函数中,以分解功能,如在实际应用程序中希望的那样:

function getTestArray(numEntries) {

  var testArray = [];

  for (var i = 0; i < numEntries; i++) {

    testArray.push(Math.random());

  }

  return testArray;

}



function testInVariable(testArray) {

  for (var i = 0; i < testArray.length; i++) {

    doSomethingAwesome(testArray[i]);

  }

}



function testInLoop(testArray) {

  var len = testArray.length;

  for (var i = 0; i < len; i++) {

    doSomethingAwesome(testArray[i]);

  }

}



function doSomethingAwesome(i) {

  return i + 2;

}



function runAndAverageTest(testToRun, testArray, numTimesToRun) {

  var totalTime = 0;

  for (var i = 0; i < numTimesToRun; i++) {

    var start = new Date();

    testToRun(testArray);

    var end = new Date();

    totalTime += (end - start);

  }

  return totalTime / numTimesToRun;

}



function runTests() {

  var smallTestArray = getTestArray(10000);

  var largeTestArray = getTestArray(10000000);



  var smallTestInLoop = runAndAverageTest(testInLoop, smallTestArray, 5);

  var largeTestInLoop = runAndAverageTest(testInLoop, largeTestArray, 5);

  var smallTestVariable = runAndAverageTest(testInVariable, smallTestArray, 5);

  var largeTestVariable = runAndAverageTest(testInVariable, largeTestArray, 5);



  console.log("Length in for statement (small array): " + smallTestInLoop + "ms");

  console.log("Length in for statement (large array): " + largeTestInLoop + "ms");

  console.log("Length in variable (small array): " + smallTestVariable + "ms");

  console.log("Length in variable (large array): " + largeTestVariable + "ms");

}



console.log("Iteration 1");

runTests();

console.log("Iteration 2");

runTests();

console.log("Iteration 3");

runTests();

为了尽可能公平地进行测试,每个测试运行5次并取平均值。我还运行了包括阵列生成在内的整个测试3次。在我的计算机上的Chrome上进行的测试表明,使用每种方法所花费的时间几乎相同。

重要的是要记住,该示例只是一个玩具示例,实际上,从您的应用程序上下文中提取的大多数示例可能会产生不可靠的信息,因为您的代码正在执行的其他操作可能会直接或间接影响性能。

底线

确定最适合您的应用程序的最佳方法是亲自对其进行测试!JS引擎,浏览器技术和CPU技术不断发展,因此必须始终在应用程序上下文中为自己测试性能。值得一问的是,您是否根本没有性能问题,如果您不花时间进行对用户而言微不足道的微优化,则最好花费时间来修复错误和添加功能,从而使用户更快乐:)。

原始答案:

后者会稍快一些。该length属性不会遍历数组以检查元素数,但是每次在数组上调用该属性时,都必须取消对该数组的引用。通过将长度存储在变量中,循环的每次迭代都不需要数组取消引用。

2020-05-01