我已经听过很多次了。向后计数时,JavaScript 循环真的更快吗?如果是这样,为什么?我已经看到一些测试套件示例显示反向循环更快,但我找不到任何解释为什么!
我假设这是因为循环不再需要在每次检查它是否完成时评估一个属性,它只是检查最终的数值。
IE
for (var i = count - 1; i >= 0; i--)
{
// count is only evaluated once and then the comparison is always on 0.
}
for
循环更快,因为上限(呵呵,下限)循环控制变量不必定义或从对象中获取;它是一个常数零。
并不是说 i--
比 i++
快。实际上,它们都同样快。
升序循环中需要时间的是评估每个 i
数组的大小。在这个循环中:
for(var i = array.length; i--;)
当您声明 i
时,您只计算一次 .length
,而对于这个循环
for(var i = 1; i <= array.length; i++)
当您检查 i <= array.length
时,每次增加 i
时都会评估 .length
。
在大多数情况下,您甚至不应该担心这种优化。
This guy 比较了许多浏览器中的许多 javascript 循环。他还有一个 test suite,因此您可以自己运行它们。
在所有情况下(除非我在阅读中错过了一个)最快的循环是:
var i = arr.length; //or 10
while(i--)
{
//...
}
--i
那么您必须在循环内使用 var current = arr[i-1];
否则它将关闭一...
我试图用这个答案给出一个广泛的画面。
括号中的以下想法是我的信念,直到我最近测试了这个问题:
[[就像 C/C++ 这样的低级语言而言,代码经过编译,以便在变量为零(或非零)时处理器具有特殊的条件跳转命令。
另外,如果您关心这么多的优化,您可以使用 ++i
而不是 i++
,因为 ++i
是单处理器命令,而 i++
表示 j=i+1, i=j
。]]
真正快速的循环可以通过展开它们来完成:
for(i=800000;i>0;--i)
do_it(i);
它可能比
for(i=800000;i>0;i-=8)
{
do_it(i); do_it(i-1); do_it(i-2); ... do_it(i-7);
}
但其原因可能相当复杂(顺便提一下,游戏中存在处理器命令预处理和缓存处理的问题)。
就高级语言而言,如您所问的JavaScript,如果您依赖库、内置函数进行循环,则可以优化事物。让他们决定如何最好地完成。
因此,在 JavaScript 中,我建议使用类似
array.forEach(function(i) {
do_it(i);
});
它也不易出错,并且浏览器有机会优化您的代码。
[备注:不仅是浏览器,您也有空间轻松优化,只需重新定义 forEach
函数(取决于浏览器),使其使用最新的最佳技巧! :) @AMK 说在特殊情况下更值得使用 array.pop
或 array.shift
。如果你这样做,把它放在窗帘后面。 最大的杀伤力是向 forEach
添加选项以选择循环算法。]
此外,对于低级语言,如果可能的话,最好的做法是使用一些智能库函数来进行复杂的循环操作。
这些库还可以将事物(多线程)放在您的背后,并且专业的程序员也可以使它们保持最新状态。
我做了更多的检查,结果发现在 C/C++ 中,即使是 5e9 = (50,000x100,000) 操作,如果针对像@alestanis 说的常量。 (JsPerf 结果有时不一致,但大体上说相同:你不能做出很大的改变。)
所以 --i
恰好是一个“豪华”的东西。它只会让你看起来像一个更好的程序员。 :)
另一方面,在这种 5e9 的情况下展开,它使我在 10 秒时从 12 秒降至 2.5 秒,在我前进 20 秒时降至 2.1 秒。它没有优化,优化已经把事情拖到了无法衡量的时间。 :) (展开可以按照我上面的方式或使用 i++
完成,但这并不能在 JavaScript 中取得进展。)
总而言之:在工作面试中保持 i--
/i++
和 ++i
/i++
差异,坚持使用 array.forEach
或其他复杂的库函数(如果可用)。 ;)
array.each(...)
可能会更好。我认为他们不会尝试解开普通的 for 循环。
+1
给你一个 Great Answer
徽章。真的很棒的答案。 :)
i--
与 i++
一样快
下面的代码和你的一样快,但是使用了一个额外的变量:
var up = Things.length;
for (var i = 0; i < up; i++) {
Things[i]
};
建议不要每次都评估数组的大小。对于大型阵列,可以看到性能下降。
for (var i=0, up=Things.length; i<up; i++) {}
Things.length
完全相同的 up
不是通过引用传递(就像对象或数组那样),而是直接通过值传递。换句话说,它完全按照数字 10 或 100000 插入到循环控件中。您只是将它重命名为 OUTSIDE 的循环,所以没有任何区别。出于这个原因,答案本身是完全有效的。当看到 i <向上循环控制看到 i < 10 不是我 < (参考数字 10)。实际上 up
在其中存储了一个原语,不要忘记这一点。
由于您对该主题感兴趣,请查看 Greg Reimer 关于 JavaScript 循环基准的博客文章What's the Fastest Way to Code a Loop in JavaScript?:
我为 JavaScript 中不同的循环编码方式构建了一个循环基准测试套件。已经有一些这样的,但我没有发现任何承认本机数组和 HTML 集合之间的区别。
您还可以通过打开 https://blogs.oracle.com/greimer/resource/loop-test.html
进行循环性能测试(如果 JavaScript 在浏览器中被例如 NoScript 阻止,则不起作用)。
编辑:
Milan Adamovsky 创建的最新基准测试可以在运行时 here 中针对不同的浏览器执行。
对于 Mac OS X 10.6 上的 Firefox 17.0 中的测试,我得到了以下循环:
https://i.stack.imgur.com/yn6kQ.png
不是 --
或 ++
,而是比较操作。使用 --
您可以与 0 进行比较,而使用 ++
您需要将其与长度进行比较。在处理器上,与零比较通常是可用的,而与有限整数比较需要减法。
a++ < length
实际上编译为
a++
test (a-length)
因此编译时处理器需要更长的时间。
我在 Sublime Text 2 中看到了同样的建议。
就像已经说过的那样,主要的改进不是在 for 循环的每次迭代中评估数组的长度。这是一种众所周知的优化技术,并且在数组是 HTML 文档的一部分时在 JavaScript 中特别有效(对所有 li
元素执行 for
)。
例如,
for (var i = 0; i < document.getElementsByTagName('li').length; i++)
比
for (var i = 0, len = document.getElementsByTagName('li').length; i < len; i++)
从我的立场来看,您问题形式的主要改进是它没有声明额外的变量(在我的示例中为 len
)
但是,如果您问我,重点不在于 i++
与 i--
优化,而是不必在每次迭代时评估数组的长度(您可以在 jsperf 上查看基准测试)。
简短的回答
对于普通代码,尤其是像 JavaScript 这样的高级语言,i++
和 i--
没有性能差异。
性能标准是在 for
循环和 compare 语句中的使用。
这适用于所有高级语言,并且大部分独立于 JavaScript 的使用。解释是最后一行的汇编代码。
详细解释
循环中可能会出现性能差异。背景是在 汇编代码 级别上,您可以看到 compare with 0
只是一个不需要额外寄存器的语句。
这种比较在循环的每一次通过时都会发出,并且可能会带来可衡量的性能改进。
for(var i = array.length; i--; )
将被评估为这样的伪代码:
i=array.length
:LOOP_START
decrement i
if [ i = 0 ] goto :LOOP_END
... BODY_CODE
:LOOP_END
请注意,0 是文字,或者换句话说,是一个常量值。
for(var i = 0 ; i < array.length; i++ )
将被评估为这样的伪代码(假定正常的解释器优化):
end=array.length
i=0
:LOOP_START
if [ i < end ] goto :LOOP_END
increment i
... BODY_CODE
:LOOP_END
请注意,end 是一个需要 CPU 寄存器的变量。这可能会在代码中调用额外的寄存器交换,并且需要在 if
语句中使用更昂贵的比较语句。
只是我的 5 美分
对于高级语言,便于维护的可读性作为较小的性能改进更为重要。
通常,从数组开始到结束的经典迭代会更好。
从数组结束到开始的更快迭代会导致可能不需要的反向序列。
后文
正如评论中所问的:--i
和 i--
的区别在于递减之前或之后对 i
的评估。
最好的解释是尝试一下;-) 这是一个 Bash 示例。
% i=10; echo "$((--i)) --> $i"
9 --> 9
% i=10; echo "$((i--)) --> $i"
10 --> 9
--i
和 i--
之间的区别?
我认为在 JavaScript 中说 i--
比 i++
快是没有道理的。
首先,它完全依赖于 JavaScript 引擎的实现。
其次,只要最简单的构造 JIT 并转换为本地指令,那么 i++
与 i--
将完全取决于执行它的 CPU。也就是说,在 ARM(移动电话)上,下降到 0 会更快,因为减量和与零比较是在单个指令中执行的。
可能,您认为一个比另一个更浪费,因为建议的方法是
for(var i = array.length; i--; )
但建议的方式不是因为一个比另一个快,而仅仅是因为如果你写
for(var i = 0; i < array.length; i++)
然后在每次迭代中必须评估 array.length
(更智能的 JavaScript 引擎可能会发现循环不会改变数组的长度)。尽管它看起来像一个简单的语句,但它实际上是由 JavaScript 引擎在后台调用的某个函数。
另一个原因,为什么 i--
可以被认为“更快”是因为 JavaScript 引擎只需要分配一个内部变量来控制循环(变量到 var i
)。如果与 array.length 或其他变量进行比较,则必须有多个内部变量来控制循环,并且内部变量的数量是 JavaScript 引擎的有限资产。循环中使用的变量越少,JIT 优化的机会就越大。这就是为什么可以认为 i--
更快...
array.length
可能值得仔细措辞。当您引用它时,长度不是计算的。 (这只是 a property that gets set whenever an array index is created or changed)。如果有额外的开销,那是因为 JS 引擎没有优化那个名字的查找链。
getLength(){return m_length; }
,因为其中涉及到一些内务处理。但是,如果您尝试向后思考:编写需要实际计算长度的数组实现将是非常巧妙的:)
length
。
dec/jnz
与 inc eax / cmp eax, edx / jne
。
由于其他答案似乎都没有回答您的具体问题(其中一半以上显示 C 示例并讨论低级语言,您的问题是针对 JavaScript)我决定自己编写。
所以,给你:
简单回答: i--
通常更快,因为它不必每次运行时都与 0 进行比较,各种方法的测试结果如下:
测试结果: 正如 this jsPerf“证明”的那样,arr.pop()
实际上是迄今为止最快的循环。但是,正如您在问题中提出的那样,专注于 --i
、i--
、i++
和 ++i
,以下是 jsPerf(它们来自多个 jsPerf,请参阅下面的来源)结果总结:
--i
和 i--
在 Firefox 中是相同的,而 i--
在 Chrome 中更快。
在 Chrome 中,基本的 for 循环 (for (var i = 0; i < arr.length; i++)
) 比 i--
和 --i
快,而在 Firefox 中则较慢。
在 Chrome 和 Firefox 中,缓存的 arr.length
显着快于 Chrome 大约 170,000 ops/sec。
没有显着差异,在大多数浏览器中,++i
比 i++
快,AFAIK,在任何浏览器中都不会反过来。
简短总结: arr.pop()
是迄今为止最快的循环;对于特别提到的循环,i--
是最快的循环。
来源: http://jsperf.com/fastest-array-loops-in-javascript/15、http://jsperf.com/ipp-vs-ppi-2
我希望这回答了你的问题。
pop
测试似乎只是这么快,因为它在循环的大部分时间里将数组大小减小到 0 - 据我所知。但是为了确保事情是公平的,我设计了这个 jsperf 以在每个测试中以相同的方式创建数组 - 这似乎表明 .shift()
是我少数浏览器的赢家 - 虽然不是我所期望的 :) jsperf.com/compare-different-types-of-looping
++i
的人而被投票赞成:D
这取决于数组在内存中的位置以及访问该数组时内存页面的命中率。
在某些情况下,由于命中率的增加,按列顺序访问数组成员比按行顺序更快。
我最后一次担心它是在编写 6502 程序集(8 位,是的!)时。最大的收获是大多数算术运算(尤其是递减)更新了一组标志,其中一个是 Z
,即“达到零”指示符。
因此,在循环结束时,您只需执行两条指令:DEC
(递减)和 JNZ
(如果不为零则跳转),无需比较!
i--
与 i++
背后的真正原因很可能是前者不会在循环范围内引入额外的控制变量。请看下面我的回答...
dec/jnz
而不是 inc/cmp/jne
用于 x86 情况。您不会看到空循环运行得更快(两者都会使分支吞吐量饱和),但倒计时会稍微减少循环开销。当前的英特尔硬件预取器也不受按降序排列的内存访问模式的困扰。我认为较旧的 CPU 可以跟踪 4 个反向流和 6 个或 10 个正向流,IIRC。
你现在这样做的方式并不快(除了它是一个无限循环之外,我猜你打算这样做 i--
.
如果您想让它更快,请执行以下操作:
for (i = 10; i--;) {
//super fast loop
}
当然你不会在这么小的循环上注意到它。它更快的原因是因为你在检查它是否为“真”时递减 i (当它达到 0 时它评估为“假”)
(i = 10; i--;)
它可以通过 JavaScript(和所有语言)最终变成操作码在 CPU 上运行来解释。 CPU 总是有一条指令用于与零进行比较,这非常快。
顺便说一句,如果您可以保证 count
始终是 >= 0
,您可以简化为:
for (var i = count; i--;)
{
// whatever
}
for(var i = array.length; i--; )
并没有快多少。但是,当您将 array.length
替换为 super_puper_function()
时,可能会明显更快(因为它在每次迭代中都会被调用)。这就是区别。
如果你打算在 2014 年改变它,你不需要考虑优化。如果您要使用“搜索和替换”进行更改,则无需考虑优化。如果你没有时间,你不需要考虑优化。但现在,你有时间考虑一下。
PS:i--
并不比 i++
快。
简而言之:在 JavaScript 中执行此操作绝对没有区别。
首先,你可以自己测试一下:
jsperf - 是用于 JavaScript 中各种性能测试的优秀平台。
http://jsperf.com/inc-vs-dec-2
您不仅可以测试和运行任何 JavaScript 库中的任何脚本,还可以访问所有以前编写的脚本,以及查看不同平台上不同浏览器中执行时间之间的差异的能力。
所以就你所见,任何环境下的性能都没有区别。
如果您想提高脚本的性能,您可以尝试执行以下操作:
有一个 var a = array.length;语句,这样您就不会在循环中每次都计算其值 Do loop unrolling http://en.wikipedia.org/wiki/Loop_unwinding
但你必须明白,你能获得的进步是如此微不足道,以至于你甚至不应该关心它。
我自己的看法为什么会出现这样的误解(Dec vs Inc)
很久很久以前,有一个通用的机器指令 DSZ(减零并跳过零)。用汇编语言编程的人使用这条指令来实现循环以保存寄存器。现在这个古老的事实已经过时了,我很确定你不会使用这种伪改进在任何语言中获得任何性能改进。
我认为在我们这个时代传播这种知识的唯一方法是阅读他人的个人代码。看到这样的结构并询问为什么要实施它,这里的答案是:“它提高了性能,因为它与零相比”。您对同事的更高知识感到困惑,并认为使用它来变得更聪明:-)
array.length
不一定会导致性能损失,仅仅是因为 JS 虚拟机足够聪明,可以判断数组是否没有被循环体修改。请看下面我的回答。
我做了一个comparison on jsbench。
正如 alestani 指出的,在升序循环中需要时间的一件事是,对于每次迭代,评估数组的大小。在这个循环中:
for ( var i = 1; i <= array.length; i++ )
每次增加 i
时都会评估 .length
。在这个:
for ( var i = 1, l = array.length; i <= l; i++ )
当您声明 i
时,您只计算一次 .length
。在这个:
for ( var i = array.length; i--; )
比较是隐式的,它发生在递减 i
之前,并且代码非常可读。但是,可以产生巨大影响的是您放入循环中的内容。
循环调用函数(在别处定义):
for (i = values.length; i-- ;) {
add( values[i] );
}
使用内联代码循环:
var sum = 0;
for ( i = values.length; i-- ;) {
sum += values[i];
}
如果你可以内联你的代码,而不是调用一个函数,而不牺牲易读性,你可以让循环快一个数量级!
注意:由于浏览器是becoming good at inlining简单的功能,这实际上取决于您的代码的复杂程度。所以,优化之前的配置文件,因为
瓶颈可能在其他地方(ajax,reflow,...)您可能会选择更好的算法您可能会选择更好的数据结构
但要记住:
代码是为人们阅读而编写的,只是为了让机器执行。
这不取决于 --
或 ++
符号,但取决于您在循环中应用的条件。
例如:如果变量具有静态值,则循环比每次循环检查条件(如数组长度或其他条件)时更快。
但是不要担心这种优化,因为这次它的效果是以纳秒为单位来衡量的。
++
与 --
无关紧要,因为 JavaScript 是一种解释型语言,而不是一种编译型语言。每条指令都翻译成不止一种机器语言,你不应该关心血淋淋的细节。
那些谈论使用 --
(或 ++
)来有效使用汇编指令的人是错误的。这些指令适用于整数运算并且有no integers in JavaScript, just numbers。
您应该编写可读的代码。
曾经有人说 --i 更快(在 C++ 中),因为只有一个结果,即递减值。 i-- 需要将递减的值存储回 i 并保留原始值作为结果 (j = i--;)。在大多数编译器中,这使用了两个寄存器而不是一个,这可能导致另一个变量必须写入内存而不是作为寄存器变量保留。
我同意其他人所说的这些天没有什么不同。
--i
更快,jsben.ch/RpG0K。 jsbench.me:i--
更快,jsbench.me/i2kkzuk4kl/1。 measurethat.net:--i
更快,measurethat.net/Benchmarks/ShowResult/162675。
有时,对我们编写代码的方式进行一些非常小的更改可能会对我们的代码实际运行的速度产生很大的影响。一个小的代码更改可以对执行时间产生很大影响的一个领域是我们有一个处理数组的 for 循环。如果数组是网页上的元素(例如单选按钮),则更改的效果最大,但即使数组位于 Javascript 代码内部,仍然值得应用此更改。
编码 for 循环以处理数组 lis 的传统方法如下:
for (var i = 0; i < myArray.length; i++) {...
这样做的问题是使用 myArray.length 评估数组的长度需要时间,而我们编写循环的方式意味着每次都必须在循环周围执行此评估。如果数组包含 1000 个元素,则数组的长度将被计算 1001 次。如果我们正在查看单选按钮并且有 myForm.myButtons.length 则评估将花费更长的时间,因为必须首先定位指定表单中的适当按钮组,然后才能在每次循环中评估长度。
显然,我们不希望在处理数组时改变数组的长度,所以所有这些长度的重新计算只是不必要地增加了处理时间。 (当然,如果你在循环中有添加或删除数组条目的代码,那么数组大小可以在迭代之间改变,所以我们不能改变测试它的代码)
对于大小固定的循环,我们可以做些什么来纠正这个问题,即在循环开始时评估一次长度并将其保存在变量中。然后我们可以测试变量来决定何时终止循环。这比每次评估数组长度要快得多,特别是当数组包含多个条目或者是网页的一部分时。
执行此操作的代码是:
for (var i = 0, var j = myArray.length; i < j; i++) {...
因此,现在我们只评估一次数组的大小,并针对每次在循环中保存该值的变量测试我们的循环计数器。这个额外变量的访问速度比评估数组的大小要快得多,因此我们的代码将比以前运行得更快。我们的脚本中只有一个额外的变量。
通常,只要数组中的所有条目都得到处理,我们处理数组的顺序并不重要。在这种情况下,我们可以通过取消我们刚刚添加的额外变量并以相反的顺序处理数组来使我们的代码稍微快一些。
以最有效的方式处理我们的数组的最终代码是:
for (var i = myArray.length-1; i > -1; i--) {...
这段代码仍然只在开始时计算一次数组的大小,但是我们没有将循环计数器与变量进行比较,而是将其与常量进行比较。由于访问常量比访问变量更有效,并且由于我们的赋值语句比以前少了,所以我们的第三版代码现在比第二版更高效,并且比第一版更高效。
在许多情况下,这与处理器可以比其他比较更快地比较零的事实基本上无关。
这是因为 only a few Javascript engines(JIT 列表中的那些)实际上会生成机器语言代码。
大多数 Javascript 引擎都会构建源代码的内部表示,然后它们会对其进行解释(要了解这是什么样的,请查看 this page on Firefox's SpiderMonkey 的底部附近)。一般来说,如果一段代码实际上做了同样的事情,但会导致更简单的内部表示,它会运行得更快。
请记住,对于简单的任务,例如从变量中添加/减去一个,或者将变量与某物进行比较,解释器从一个内部“指令”移动到下一个内部“指令”的开销是相当高的,因此更少的“指令”是由JS引擎内部使用,效果更好。
好吧,我不了解 JavaScript,它实际上应该只是重新评估数组长度的问题,也许与关联数组有关(如果你只递减,不太可能需要分配新条目 - 如果数组是密集的,也就是说。有人可能会为此优化)。
在低级汇编中,有一个循环指令,称为 DJNZ(如果非零则递减和跳转)。因此,递减和跳转都在一条指令中,使其可能比 INC 和 JL / JB 稍微快一点(递增,如果小于则跳转/如果低于则跳转)。此外,与零比较比与另一个数字比较更简单。但所有这些实际上都是微不足道的,并且还取决于目标架构(例如在智能手机中的 Arm 上可能会有所不同)。
我没想到这种低级差异会对解释语言产生如此大的影响,我只是没有在回复中看到 DJNZ,所以我想我会分享一个有趣的想法。
DJNZ
是 8051 (z80) ISA 中的指令。 x86 有 dec/jnz
而不是 inc/cmp/jne
,显然 arm 有类似的东西。我很确定这不是 Javascript 差异的原因;那是在循环条件中有更多到 eval 。
用非常简单的话
“i-- 和 i++。实际上,它们都需要相同的时间”。
但是在这种情况下,当您进行增量操作时..处理器在每次变量增加 1 时评估 .length 并且在减少的情况下..特别是在这种情况下,它只会评估 .length 一次,直到我们得到 0。
首先,i++
和 i--
在任何编程语言(包括 JavaScript)上花费的时间完全相同。
下面的代码需要很多不同的时间。
快速地:
for (var i = 0, len = Things.length - 1; i <= len; i++) { Things[i] };
减缓:
for (var i = 0; i <= Things.length - 1; i++) { Things[i] };
因此以下代码也需要不同的时间。
快速地:
for (var i = Things.length - 1; i >= 0; i--) { Things[i] };
减缓:
for (var i = 0; i <= Things.length - 1; i++) { Things[i] };
由于编译器的优化,PS Slow 仅对少数语言(JavaScript 引擎)很慢。最好的方法是使用 '<' 代替 '<='(或 '=')和 '--i' 代替 'i--'。
i-- 或 i++ 消耗的时间并不多。如果您深入 CPU 架构,++
比 --
更快,因为 --
操作将执行 2 的补码,但它发生在硬件内部,因此这将使其速度更快,并且两者之间没有重大区别++
和 --
这些操作也被认为是 CPU 消耗的最少时间。
for 循环运行如下:
在开始时初始化变量一次。
检查循环的第二个操作数中的约束,<、>、<= 等。
然后应用循环。
增加循环并再次循环再次抛出这些过程。
所以,
for (var i = Things.length - 1; i >= 0; i--) {
Things[i]
};
将在开始时仅计算一次数组长度,这不是很多时间,但是
for(var i = array.length; i--; )
会计算每个循环的长度,所以会消耗很多时间。
var i = Things.length - 1; i >= 0; i--
也会计算长度 1 次。
--
操作将做 2 的补码”是什么意思,但我认为这意味着它会否定某些东西。不,它不会否定任何架构上的任何内容。减 1 就像加 1 一样简单,你只需创建一个借用而不是进位的电路。
回答此类问题的最佳方法是实际尝试。设置一个计算一百万次迭代或其他的循环,并以两种方式进行。对两个循环进行计时,并比较结果。
答案可能取决于您使用的浏览器。有些会产生与其他人不同的结果。
喜欢它,很多标记但没有答案:D
简单地说,与零的比较总是最快的比较
所以 (a==0) 实际上返回 True 比 (a==5) 更快
它很小且微不足道,并且在一个集合中有 1 亿行,它是可测量的。
即在循环中,您可能会说 i <= array.length 并递增 i
在向下循环中,您可能会说 where i >= 0 而是递减 i。
比较比较快。不是循环的“方向”。
帮助他人避免头痛 --- 投票!
此页面上最受欢迎的答案不适用于 Firefox 14,并且未通过 jsLinter。 “while”循环需要比较运算符,而不是赋值。它确实适用于 chrome、safari 甚至 ie。但死在Firefox中。
这已破了!
var i = arr.length; //or 10
while(i--)
{
//...
}
这会起作用的! (在 Firefox 上工作,通过 jsLinter)
var i = arr.length; //or 10
while(i>-1)
{
//...
i = i - 1;
}
while (i--)
并且可以在许多浏览器上运行的示例。你的测试可能有什么奇怪的地方吗?您使用的是 Firefox 14 的测试版吗?
这只是一个猜测,但可能是因为处理器更容易将某些内容与 0 ( i >= 0 ) 进行比较,而不是与另一个值 ( i < Things.length) 进行比较。
不定期副业成功案例分享
.length
一定次数或声明和定义一个新变量会更快吗?在大多数情况下,这是过早的(并且是错误的)优化,除非您的length
的评估成本非常高。0
的评估速度比array.length
快。嗯,据说。.length
是否在for loop
的声明中并不重要。