什么是在JavaScript中循环访问数组的最快方法?

我从书本上了解到,你应该这样写:

for(var i=0, len=arr.length; i < len; i++){ // blah blah } 

所以arr.length不会每次计算。

其他人则说编译器会对此做一些优化,所以你可以写:

 for(var i=0; i < arr.length; i++){ // blah blah } 

我只想知道在实践中哪个是最好的方法?

用最现代的浏览器进行这个testing之后…

http://jsben.ch/#/y3SpC

目前 ,最快的循环forms(在我看来,语法最明显)。

具有长度caching的循环标准

 for (var i = 0, len = myArray.length; i < len; i++) { } 

我会说这绝对是一个我赞扬JavaScript引擎开发人员的情况。 运行时间应该为了清晰 而不是巧妙而优化。

通过JavaScript数组循环的绝对最快的方法是:

 var len = arr.length; while (len--) { // blah blah } 

请参阅http://blogs.oracle.com/greimer/entry/best_way_to_code_a进行全面比较;

如果顺序不重要,我更喜欢这种风格:

 for(var i = array.length; i--; ) 

它caching的长度,写得更短。 但它会以相反的顺序遍历数组。

2014 While回来了

只是想逻辑。

看这个

 for( var index = 0 , length = array.length ; index < length ; index++ ) { //do stuff } 
  1. 需要创build至less2个variables(索引,长度)
  2. 需要检查索引是否小于长度
  3. 需要增加索引
  4. for循环有3个参数

现在告诉我为什么这应该比以下更快:

 var length = array.length; while( --length ) { //or length-- //do stuff } 
  1. 一个variables
  2. 没有检查
  3. 指数下降(机器更喜欢)
  4. while只有一个参数

当Chrome 28显示for循环比while循环更快时,我完全感到困惑。 这肯定有某种好处

“呃,每个人都在使用for循环,让我们专注于为Chrome开发。”

但是现在,在2014年,while循环又回来了。 它快了2倍,在其他/旧版浏览器上它总是更快。

最近我做了一些新的testing。 现在在现实世界中,这些短代码是没有价值的,jsperf实际上不能正确执行while循环,因为它需要重新创buildarray.length,这也需要时间。

你不能得到jsperf的while循环的实际速度。

你需要创build你自己的自定义函数,并用window.performance.now()

是的,没有办法,while循环只是更快。

真正的问题实际上是dom操作/渲染时间/绘制时间,或者你想调用它。

例如,我有一个canvas场景,我需要计算坐标和碰撞…这是在10-200微秒(而不是毫秒)之间完成的。 它实际上需要不同的毫秒来渲染一切。

在某些情况下,使用for loop还有另一种超级执行方式…例如复制/克隆数组

 for( var i = array.length ; i > 0 ; arrayCopy[ --i ] = array[ i ] // doing stuff ); 

注意参数的设置:

  1. 和while循环一样,我只使用一个variables
  2. 需要检查索引是否大于0;
  3. 正如你可以看到这个方法是不同的,每个人都使用正常的循环,因为我做的东西里面的第三个参数,我也直接减less数组内。

说,这证实了机器喜欢 –

写我正在考虑使它变短一点,删除一些无用的东西,并使用相同的风格写这个:

 for( var i = array.length ; i-- ; arrayCopy[ i ] = array[ i ] // doing stuff ); 

即使它更短,它看起来像使用i再一次减慢了一切。 它比前一个循环和一个循环慢1/5。

注意: 之后是非常重要的for looo without {}

即使我只是告诉你,jsperf不是testing脚本的最佳方法..我在这里添加了2个循环

http://jsperf.com/caching-array-length/40

这里是另一个关于JavaScript性能的答案

https://stackoverflow.com/a/21353032/2450730

这个答案是显示高效的写作方式的JavaScript。 所以,如果你不能阅读,问,你会得到一个答案或阅读关于JavaScript的书http://www.ecma-international.org/ecma-262/5.1/

截至2016年6月 ,在最新的Chrome浏览器(2016年5月浏览器市场的71%,并增加)进行一些testing:

  • 最快的循环是一个循环 ,无论是否有caching长度提供真正相似的性能。 (具有caching长度的for循环有时会比没有caching的情况提供更好的结果,但差别几乎可以忽略不计,这意味着引擎可能已经被优化以支持标准,而且可能最直接的用于没有caching的循环。
  • 递减的while循环大约比for循环慢1.5倍。
  • 使用callback函数的循环(比如forEach的标准)比for循环慢大约10倍。

我认为这个线程太旧了,错误的程序员认为他们需要caching长度,或者使用递减遍历来实现更好的性能,编写比简单直接的循环更不易读,更容易出错的代码。 所以我build议:

  • 如果您的应用程序遍历了很多项目,或者您的循环代码位于经常使用的函数中,那么直接循环就是答案:

     for (var i = 0; i < arr.length; i++) { // Do stuff with arr[i] or i } 
  • 如果你的应用程序没有真正地迭代大量的项目,或者你只需​​要在这里和那里做小的迭代,使用标准的forEachcallback或从你select的JS库中的任何类似的函数可能会更容易理解,索引variables作用域被closures,你不需要使用括号,直接访问数组值:

     arr.forEach(function(value, index) { // Do stuff with value or index }); 
  • 如果您真的需要在几十毫秒的时间内重复几十毫秒,并且数组的长度在整个过程中不变,那么可以考虑在for循环中caching长度。 虽然我觉得现在真的没这个必要了:

     for (var i = 0, len = arr.length; i < len; i++) { // Do stuff with arr[i] } 

http://jsperf.com/caching-array-length/60

我准备的(通过重复使用较旧的)最新的testing版本显示了一件事。

caching的长度并不是那么重要,但是并没有什么坏处。

在我的Debian Squeeze 64位( 我的桌面硬件 )中,每一次上面链接的testing(在新近打开的标签上)都能为Chrome,Opera和Firefox中的最后4个片段(图表中的第3,第5,第7和第10) )。 后续运行给出了完全不同的结果。

性能明智的结论很简单:

  • 去循环(向前)和testing使用!==而不是<
  • 如果以后不需要重用数组,那么循环减less的长度和破坏性的shift()数组也是有效的。

TL;博士

如今(2011.10)以下模式看起来是最快的。

 for (var i = 0, len = arr.length; i !== len; i++) { ... } 

注意cachingarr.length在这里并不重要,所以你可以testingi !== arr.length并且性能不会下降,但是你会得到更短的代码。


PS:我知道在使用shift()代码片段中,可以使用它的结果而不是访问第0个元素,但是我忽略了在重新使用之前的修订版本(while循环有错误)之后,后来我不想失去已经获得的结果。

纯粹performance中的“最佳”? 或性能可读性?

纯性能“最好”是这样的,它使用caching和++前缀操作符(我的数据: http : //jsperf.com/caching-array-length/189 )

 for (var i = 0, len = myArray.length; i < len; ++i) { // blah blah } 

我认为无caching的for循环是执行时间和程序员读取时间的最佳平衡。 每一个以C / C ++ / Java开始的程序员都不会浪费一个不得不阅读这个的程序员

 for(var i=0; i < arr.length; i++){ // blah blah } 

**caching循环内的数组长度,几秒钟的时间将被避免。 如果数组中有更多项目,则取决于数组中的项目,这与时间Ms有很大的区别*

**

 sArr; //Array[158]; for(var i = 0 ; i <sArr.length ; i++) { callArray(sArr[i]); //function call } ***end: 6.875ms*** 

**

**

 sArr; //Array[158]; for(var i = 0,len = sArr.length ; i < len ; i++) { callArray(sArr[i]); //function call } ***end: 1.354ms*** 

**

这看起来是迄今为止最快的方式 …

 var el; while (el = arr.shift()) { el *= 2; } 

考虑到这将消耗arrays,吃它,并留下一切…

我总是写在第一种风格。

即使编译器足够聪明,可以对数组进行优化,但是如果我们在这里使用DOMNodeList还是一些计算长度的复杂对象,它仍然很聪明?

我知道数组的问题是什么,但是我认为将所有的循环写入一种风格是一个好习惯。

这是2017年

我做了一些testing。

https://jsperf.com/fastest-way-to-iterate-through-an-array/

看起来像方法是在Chrome上最快的。

看起来左边的递减( --i )比Firefox上的其他( ++ii++i++ )要快得多。

这种方法是平均禁食。 但它以相反的顺序迭代数组。

 let i = array.length; while (--i >= 0) { doSomething(array[i]); } 

如果转发订单很重要,请使用此方法。

 let ii = array.length; let i = 0; while (i < ii) { doSomething(array[i]); ++i; } 
 var arr = []; // The array var i = 0; while (i < arr.length) { // Do something with arr[i] i++; } 

我++比++更快,–i和i–

此外,你可以保存最后一行,你需要访问我最后一次做arr [i ++](但这很难debugging)。

你可以在这里testing它(与其他循环testing): http : //jsperf.com/for-vs-whilepop/5

我知道的最优雅的解决scheme是使用地图。

 var arr = [1,2,3]; arr.map(function(input){console.log(input);}); 

我已经尝试了一些其他方法来迭代一个巨大的数组,发现将数组长度减半,然后在一个循环中迭代两个半部分的速度会更快。 处理巨大的数组时可以看到这种性能差异。

 var firstHalfLen =0; var secondHalfLen = 0; var count2=0; var searchterm = "face"; var halfLen = arrayLength/2; if(arrayLength%2==halfLen) { firstHalfLen = Math.ceil(halfLen); secondHalfLen=Math.floor(halfLen); } else { firstHalfLen=halfLen; secondHalfLen=halfLen; } for(var firstHalfCOunter=0,secondHalfCounter = arrayLength-secondHalfLen; firstHalfCOunter < firstHalfLen; firstHalfCOunter++) { if(mainArray[firstHalfCOunter].search(new RegExp(searchterm, "i"))> -1) { count2+=1; } if(secondHalfCounter < arrayLength) { if(mainArray[secondHalfCounter].search(new RegExp(searchterm, "i"))> -1) { count2+=1; } secondHalfCounter++; } } 

一些性能比较(使用timer.js)之间的caching长度for循环VS上述方法。

http://jsfiddle.net/tejzpr/bbLgzxgo/

另一个jsperf.comtesting: http ://jsperf.com/while-reverse-vs-for-cached-length

while while循环似乎是最快的。 唯一的问题是,而( – i)将停在0。我怎样才能访问我的循环中的数组[0]呢?

截至2017年9月, 这些jsperftesting显示以下模式在Chrome 60上performance最佳:

 function foo(x) { x; }; arr.forEach(foo); 

有人能够重现吗?

一个基本的while循环往往是最快的。 jsperf.com是一个伟大的沙箱来testing这些types的概念。

https://jsperf.com/fastest-array-loops-in-javascript/24