For 循环性能:将数组长度存储在变量中 [英] For-loop performance: storing array length in a variable

查看:22
本文介绍了For 循环性能:将数组长度存储在变量中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

for (var i = 0; i 

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

无论如何,后者比前者快吗?

解决方案

更新:16/12/2015

由于这个答案似乎仍然获得了很多观点,随着浏览器和 JS 引擎的不断发展,我想重新审视这个问题.

我没有使用 JSPerf,而是将一些代码放在一起,使用原版中提到的两种方法循环遍历数组问题.我已将代码放入函数中以分解功能,希望在现实世界的应用程序中可以做到:

function getTestArray(numEntries) {var testArray = [];for (var i = 0; i 

为了使测试尽可能公平,每个测试运行 5 次,然后取平均值.我还运行了整个测试,包括生成数组 3 次.在我的机器上用 Chrome 测试表明,使用每种方法所花费的时间几乎相同.

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

底线

确定最适合您的应用程序的最佳方法是自己测试!JS 引擎、浏览器技术和 CPU 技术在不断发展,因此您必须始终在应用程序的上下文中为自己测试性能.还值得问问自己您是否有性能问题,如果没有,那么花时间进行用户无法察觉的微优化可能会更好地用于修复错误和添加功能,从而使用户更快乐:).

原答案:

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

如果您对在 javascript 中循环遍历数组的不同方式的性能感兴趣,请查看此 jsperf

Consider two versions of the same loop iteration:

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

and

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

Is the latter version anyhow faster than the former one?

解决方案

Update: 16/12/2015

As this answer still seems to get a lot of views I wanted to re-examine the problem as browsers and JS engines continue to evolve.

Rather than using JSPerf I've put together some code to loop through arrays using both methods mentioned in the original question. I've put the code into functions to break down the functionality as would hopefully be done in a real world application:

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();

In order to achieve as fair a test as possible each test is run 5 times and the results averaged. I've also run the entire test including generation of the array 3 times. Testing on Chrome on my machine indicated that the time it took using each method was almost identical.

It's important to remember that this example is a bit of a toy example, in fact most examples taken out of the context of your application are likely to yield unreliable information because the other things your code is doing may be affecting the performance directly or indirectly.

The bottom line

The best way to determine what performs best for your application is to test it yourself! JS engines, browser technology and CPU technology are constantly evolving so it's imperative that you always test performance for yourself within the context of your application. It's also worth asking yourself whether you have a performance problem at all, if you don't then time spent making micro optimizations that are imperceptible to the user could be better spent fixing bugs and adding features, leading to happier users :).

Original Answer:

The latter one would be slightly faster. The length property does not iterate over the array to check the number of elements, but every time it is called on the array, that array must be dereferenced. By storing the length in a variable the array dereference is not necessary each iteration of the loop.

If you're interested in the performance of different ways of looping through an array in javascript then take a look at this jsperf

这篇关于For 循环性能:将数组长度存储在变量中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆