几年前,我听说每次循环运行时都会评估 for 循环的条件部分。此外,该财产访问相对昂贵。
从那时起我就养成了将 for 循环写成这样的习惯:
var data = [1,2,3,4,5,6];
for (var i=0, l=data.length; i<l; i++) {
// do stuff
}
这是不必要的优化吗?现代 Javascript 编译器/解释器是否已经优化了条件部分,因此长度属性不会被多次访问?
这到底有多大影响?
这是不必要的优化吗?
是的,几乎总是如此。我确信每个 JavaScript 实现都具有
O(1)
的复杂性来获取长度。我能想象的唯一一个你真正想要使用哪怕是最微小的优化的情况就是游戏引擎。但如果您编写一个“普通”JavaScript 应用程序,那真的没关系 - 如果没有这种优化,您的代码会更好读。
您还需要看到与循环体相比可能出现的性能损失。它很可能涉及访问其他变量、正在迭代的元素的属性,甚至修改 DOM(这通常非常昂贵)。
如果在大多数情况下循环性能是一个大问题,那么您可以非常确定供应商不会实现
Array.prototype.forEach()
,这会带来每次“迭代”的函数调用的开销 - 与 DOM 操作相比(这特别有可能)如果使用 jQuery 的 .each()
)即使这样也很便宜。
除了 ThiefMaster 所说的之外,通常使用以下内容迭代数组:
var arr = [1, 2, 3];
arr.forEach(function(el, i) {
//...
});
或
$.each(arr, function(i, el){
//...
});
如果每次迭代调用整个函数通常是可以接受的,那么检查数组的长度几乎肯定是可以接受的。
查看一下:https://blogs.oracle.com/greimer/entry/best_way_to_code_a
在 Mozilla 中:
for (var i=0; i<arr.length; i++) //4ms
for (var i=0, len=arr.length; i<len; i++) //3ms
我认为这是一个lycorn问题。
这种特殊情况非常常见,因此可以肯定地认为它已经过优化。 例如,在 Java 中,for 循环在他们的文档中被列为他们将优化边界检查的唯一情况(在 Java 中这是一项昂贵的事情)。
我建议以另一种方式看待它:如果这种可以想象到的最常见的情况没有得到优化,那么很可能在许多其他情况下您的特定引擎没有优化......如此之多,以至于这个想法手动优化似乎有点可笑。