我从书中学到,你应该这样写for循环:
for(var i=0, len=arr.length; i < len; i++){
// blah blah
}
所以arr。每次不计算长度。
其他人说编译器会做一些优化,所以你可以这样写:
for(var i=0; i < arr.length; i++){
// blah blah
}
我只是想知道在实践中哪种方法是最好的?
我从书中学到,你应该这样写for循环:
for(var i=0, len=arr.length; i < len; i++){
// blah blah
}
所以arr。每次不计算长度。
其他人说编译器会做一些优化,所以你可以这样写:
for(var i=0; i < arr.length; i++){
// blah blah
}
我只是想知道在实践中哪种方法是最好的?
当前回答
虽然这是一个非常古老的问题,但也是一个非常有趣的问题,
请原谅我稍微改变一下这个问题,但我会在最后回答这个问题。
这个问题让我问自己,在js中是否有更好的循环方法:
所以我做了一些测试,以下是我的发现:
对于1000_000记录:最好是forEach。
对于100条记录:这根本不重要。
回到你刚才的问题:
我创建的例子和问题不完全一样。但我发现了一些有趣的事情:
首先,就像你说的,arr。如果它在比较语句I < arr内,Length每次都会计算。长度……
注意:下面的arrLength变量不超过1000_000条记录的数量。
例如:这不会工作
但是这个会
这需要0.036秒。与数字不变的情况相比,这是非常大的……
总之,
最好使用FOREACH
在你的例子中,i<arr。长度需要更多的时间(通常在1.3左右)
请参阅测试: 查看测试
其他回答
试试这个:
var myarray =[],
i = myarray.lenght;
while(i--){
// do somthing
}
我所知道的最优雅的解决方案是使用地图。
var arr = [1,2,3];
arr.map(function(input){console.log(input);});
http://jsperf.com/caching-array-length/60
我准备的最新版本的test(通过重用旧版本)显示了一件事。
缓存长度并不是那么重要,但也没有坏处。
在Chrome、Opera和Firefox中,在我的Debian Squeeze 64位(我的桌面硬件)中,每次第一次运行上面链接的测试(在新打开的选项卡上),最后4个片段(图表中的第3、第5、第7和第10)的结果都是最好的。随后的运行给出了完全不同的结果。
性能方面的结论很简单:
使用for循环(向前)并使用!==而不是<进行测试。 如果以后不需要重用数组,那么while循环减去长度和破坏性shift()-ing数组也是有效的。
博士tl;
现在(2011.10)下面的模式看起来是最快的。
for (var i = 0, len = arr.length; i !== len; i++) {
...
}
注意缓存。长度在这里并不重要,所以您可以只测试I !== arr。长度和性能不会下降,但是代码会变短。
PS:我知道在snippet with shift()中,它的结果可以用来代替访问第0个元素,但我在重用以前的修订(有错误的while循环)后忽视了这一点,后来我不想失去已经获得的结果。
我已经尝试了一些其他方法来迭代一个巨大的数组,并发现将数组长度减半,然后在一个循环中迭代这两部分更快。这种性能差异可以在处理大型数组时看到。
var firstHalfLen =0;
var secondHalfLen = 0;
var count2=0;
var searchterm = "face";
var halfLen = arrayLength/2;
if(arrayLength%2==halfLen)
{
firstHalfLen = Math.ceil(halfLen);
secondHalfLen=Math.floor(halfLen);
}
else
{
firstHalfLen=halfLen;
secondHalfLen=halfLen;
}
for(var firstHalfCOunter=0,secondHalfCounter = arrayLength-secondHalfLen;
firstHalfCOunter < firstHalfLen;
firstHalfCOunter++)
{
if(mainArray[firstHalfCOunter].search(new RegExp(searchterm, "i"))> -1)
{
count2+=1;
}
if(secondHalfCounter < arrayLength)
{
if(mainArray[secondHalfCounter].search(new RegExp(searchterm, "i"))> -1)
{
count2+=1;
}
secondHalfCounter++;
}
}
缓存长度for循环与上面的方法之间的一些性能比较(使用timer.js)。
http://jsfiddle.net/tejzpr/bbLgzxgo/
在使用大多数现代浏览器执行此测试后: https://jsben.ch/wY5fo
目前,最快的循环形式(在我看来也是语法上最明显的)。
具有长度缓存的标准for循环
var i = 0, len = myArray.length;
while (i < len) {
// your code
i++
}
我想说,这绝对是我为JavaScript引擎开发者喝彩的地方。运行时应该优化为清晰,而不是聪明。