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

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

问题描述

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

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

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

后面的版本是否比前者更快?

:16/12/2015



由于这个答案似乎仍然得到很多意见,我想重新审视浏览器和JS引擎的问题进化。



与使用JSPerf相比,我将一些代码放在一起使用原始问题中提到的两种方法循环数组。我已经把代码放到了函数中去,这样就可以在真实世界的应用程序中完成这些功能了:

  function getTestArray(numEntries){
var testArray = []; (var i = 0; i< numEntries; i ++){
testArray.push(Math.random());
}
return testArray;


函数testInVariable(testArray){
for(var i = 0; i< testArray.length; i ++){
doSomethingAwesome(testArray [i] );



函数testInLoop(testArray){
var len = testArray.length;
for(var i = 0; i< len; i ++){
doSomethingAwesome(testArray [i]);



函数doSomethingAwesome(i){
return i + 2;


函数runAndAverageTest(testToRun,testArray,numTimesToRun){
var totalTime = 0; (var i = 0; i< numTimesToRun; i ++){
var start = new Date();
testToRun(testArray);
var end = new Date();
totalTime + =(end - start);
}
返回totalTime / numTimesToRun;


函数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);
$ b $ console.log(长度为for语句(小数组):+ smallTestInLoop +ms);
console.log(在for语句中的长度(大数组):+ largeTestInLoop +ms);
console.log(变量中的长度(小数组):+ smallTestVariable +ms);
console.log(变量中的长度(大数组):+ largeTestVariable +ms);
}

runTests();
runTests();
runTests();

为了尽可能公平地进行测试,每个测试运行5次,结果取平均值。我也运行了整个测试,包括3次数组的生成。 Chrome在我的机器上测试表明,使用每种方法的时间几乎是相同的。

请记住,这个例子有点玩具的例子,事实上,从应用程序的上下文中抽取的大部分示例都可能产生不可靠的信息,因为代码执行的其他操作可能会直接或间接地影响性能。
$ b

底线

确定最适合您的最佳方式应用程序是自己测试它! JS引擎,浏览器技术和CPU技术不断发展,所以您必须始终在自己的应用程序环境中测试自己的性能。还有一点值得问问自己,你是否有性能问题,如果你没有花费时间进行微观优化,而这些优化对于用户来说是微不足道的,那么可以更好地修复错误和增加功能,从而导致更快乐的用户:)。 p>

原始答案:

后一个会稍微快一点。 长度属性不会迭代数组以检查元素的数量,但是每次在数组上调用该数组时,都必须解除引用。通过将长度存储在一个变量中,每次循环迭代都不需要数组解除引用。



如果您对通过数组循环的不同方式的性能感兴趣在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");
}

runTests();
runTests();
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-loop性能:将数组长度存储在变量中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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