我读到建议优化 JavaScript 中的循环 not reading the length attribute of an array every iteration in the loop header .
所以,我们应该这样做:
var names = ['George','Ringo','Paul','John'];
for(var i=0,j=names.length;i<j;i++){// Read array length once and assign it to a variable
doSomeThingWith(names[i]);
}
而不是这个:
var names = ['George','Ringo','Paul','John'];
for(var i=0;i<names.length;i++){
doSomeThingWith(names[i]);
}
但是,我created a small testcase比较这两种技术,但有时第一种情况更快,有时第二种情况更快。
您会推荐哪个版本?
最佳答案
首先,我应该说这个答案是在 2011 年写的,这些事情随着时间的推移而改变(因为浏览器解释器优化了越来越多的东西),所以如果你真的想知道世界的当前状态,你必须运行测试在当前浏览器上。
运行你的own jsperf test在任何版本的 IE 上。在那里您将看到两种方法或许多其他旧浏览器之间的一致差异。显然你只在 Chrome 上运行它,它速度如此之快且如此优化,以至于两种方法之间的差异可以忽略不计。在 IE9(可能比 IE7 和 IE8 更好)上,预缓存长度的方法快了 31%。
A jsperf test designed for this question给出了这个问题的定量结果。在像这样的问题中,应该去 jsperf 看看真正的区别是什么,而不是进行这么多猜测。
它显示了我尝试过的浏览器的差异,范围从几乎没有差异到相当大的差异,具体取决于浏览器。 在 Chrome 中,几乎没有区别。在 IE9 中,首先存储长度几乎快了 50%。
现在,这种速度差异对您的脚本是否重要取决于具体的代码。如果您有一个经常循环的巨大数组,那么在某些浏览器中使用这种形式可能会产生有意义的变化:
for (var i = 0, len = list.length; i < len; i++) {
// do code here
}
在slightly different test case中当使用某些 DOM 函数返回的实时伪数组时,速度上仍然存在差异,但没有那么放大(我预计 DOM 伪实时数组上的差异会更大,但事实并非如此)。
在实践中,当我不认为我的代码部分对速度至关重要和/或数组不大并且我会使用预缓存的较长版本时,我倾向于使用短版本(较少打字)如果我有意识地考虑速度或者数组很大或者我在同一个数组上进行大量迭代,则长度。
预缓存长度还有其他几个编程原因。如果您将在循环期间将元素添加到数组的末尾,并且不希望循环迭代这些新添加的元素,那么您将需要预加载长度并且仅迭代最初存在的元素.
for (var i = 0, len = list.length; i < len; i++) {
if (list[i] == "whatever") {
list.push("something");
}
}
请记住,浏览器在不断发展并添加越来越多的优化,因此在 2011 年显示出巨大优势的优化可能会本质上内置到 future 更现代的浏览器中,因此不再需要手动编码的优化。因此,如果您尝试针对当今的性能优化某些内容,则必须在当今的浏览器中进行测试,而不能仅仅依赖于您读过的可能是几年前的内容。
关于javascript - 优化 JavaScript for 循环真的有必要吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6973942/