2

几年前,我听说每次循环运行时都会评估 for 循环的条件部分。此外,访问财产的成本相对较高。

从那时起,我养成了将 for 循环编写为的习惯:

var data = [1,2,3,4,5,6];
for (var i=0, l=data.length; i<l; i++) {
    // do stuff
}

这是不需要的优化吗?现代 Javascript 编译器/解释器是否已经优化了条件部分,因此不会多次访问长度属性?

这到底有多大的影响?

4

4 回答 4

3

这是不需要的优化吗?

是的,几乎总是如此。我确信每个 JavaScript 实现都有O(1)复杂性来获取长度。我能想象到的唯一一个你真正想要使用即使是最微小的优化的地方是游戏引擎。但是,如果您编写一个“普通”的 JavaScript 应用程序,这真的无关紧要——如果没有这种优化,您的代码会更易于阅读。

您还需要查看与循环主体相比可能存在的性能损失。它很可能涉及访问其他变量、您正在迭代的元素的属性,甚至修改 DOM(这通常非常昂贵)。

如果在大多数情况下循环性能是一个大问题,那么您可以很确定供应商不会实现Array.prototype.forEach()每次“迭代”都会带来函数调用的开销 - 与 DOM 操作相比(这在 jQuery 的情况下尤其可能.each()是使用)即使是便宜的。

于 2012-12-11T22:27:04.417 回答
1

除了 ThiefMaster 所说的之外,使用以下内容迭代数组是很常见的:

var arr = [1, 2, 3];
arr.forEach(function(el, i) {
   //...
});

或者

$.each(arr, function(i, el){
   //...
});

如果每次迭代调用一个完整的函数通常是可以接受的,那么检查数组的长度几乎肯定是可以接受的。

于 2012-12-11T22:29:26.873 回答
1

看看这个: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问题。

于 2012-12-11T22:31:10.917 回答
0

这种特殊情况非常普遍,可以安全地假设它已经过优化。例如,在 Java 中,for 循环在他们的文档中被列为他们将优化边界检查的唯一情况(在 java 中这是一件昂贵的事情)。

我建议以另一种方式看待它:如果可以想象的最常见情况没有优化,那么很可能还有许多其他情况您的特定引擎没有优化......这么多的想法手动优化似乎有点可笑。

于 2013-09-01T04:08:52.073 回答