这话我听过好几次了。JavaScript循环在向后计数时真的更快吗?如果有,为什么?我已经看到了一些测试套件示例,它们显示反向循环更快,但我找不到任何解释!
我假设这是因为循环不再需要在每次检查属性时评估它是否已经完成,它只检查最终的数值。
即。
for (var i = count - 1; i >= 0; i--)
{
// count is only evaluated once and then the comparison is always on 0.
}
这话我听过好几次了。JavaScript循环在向后计数时真的更快吗?如果有,为什么?我已经看到了一些测试套件示例,它们显示反向循环更快,但我找不到任何解释!
我假设这是因为循环不再需要在每次检查属性时评估它是否已经完成,它只检查最终的数值。
即。
for (var i = count - 1; i >= 0; i--)
{
// count is only evaluated once and then the comparison is always on 0.
}
当前回答
曾经有人说——i(在c++中)更快,因为只有一个结果,即递减的值。I——需要将减后的值存储回I,并保留原始值作为结果(j = I——;)。在大多数编译器中,这会占用两个而不是一个寄存器,这可能会导致另一个变量必须写入内存,而不是作为寄存器变量保留。
我同意其他人的看法,他们说现在没有什么不同。
其他回答
简单地说
“i——和i++。实际上,它们都需要相同的时间。”
但在这种情况下,当你进行增量操作。处理器计算.length每个时间变量都加1,如果减量..特别是在这种情况下,它只计算一次。length直到得到0。
它取决于数组在内存中的位置,以及访问该数组时内存页面的命中率。
在某些情况下,按列顺序访问数组成员比按行顺序访问快,因为命中率增加了。
这并不依赖于——或++符号,而是取决于你在循环中应用的条件。
例如:如果变量有一个静态值,那么循环会比每次循环都检查条件(比如数组的长度或其他条件)更快。
但是不用担心这种优化,因为这次它的效果是以纳秒为单位衡量的。
不是——或++,而是比较操作。使用——,你可以使用与0比较,而使用++,你需要与长度比较。在处理器上,与零的比较通常是可用的,而与有限整数的比较则需要减法。
a++ < length
实际编译为
a++
test (a-length)
所以它在编译时在处理器上花费的时间更长。
我试图用这个答案给出一个广泛的图景。
以下括号中的想法是我的想法,直到我最近测试了这个问题:
对于像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函数(依赖于浏览器),以便它使用最新的最佳技巧!]: @A.M.K。表示在特殊情况下更值得使用数组。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++的区别来面试,坚持数组。forEach或其他复杂的库函数。;)