在JavaScript中,循环遍历数组的最快方法是什么?
在2016年6月,我在最新版本的Chrome浏览器上进行了一些测试(2016年5月占浏览器市场份额的71%,并且在增长中):
- 最快的循环是使用for循环,使用缓存长度和不使用缓存长度的性能非常相似。(使用缓存长度的for循环有时会比不使用缓存的那个效果好,但差异几乎可以忽略不计,这意味着引擎可能已经被优化为支持标准和可能最直接的for循环)。
- 使用递减的while循环比for循环慢大约1.5倍。
- 使用回调函数的循环(如标准的forEach)比for循环慢约10倍。
我认为这个帖子太旧了,它误导了程序员,认为他们需要缓存长度,或者使用递减的反向遍历来获得更好的性能,而写出的代码不够易读,更容易出错,而一个简单直接的for循环更好。因此,我建议:
- 如果你的应用程序需要遍历大量的项,或者你的循环代码经常在一个函数中使用,那么直接使用for循环就可以了:
for (var i = 0; i < arr.length; i++) { // Do stuff with arr[i] or i }
- 如果你的应用程序不需要遍历大量的项,或者你只需要偶尔进行小的迭代,使用标准的forEach回调或者你所选择的JS库中的任何类似函数可能更易于理解,而且更不容易出错,因为索引变量的作用域是封闭的,不需要使用括号,可以直接访问数组的值:
arr.forEach(function(value, index) { // Do stuff with value or index });
- 如果你真的需要在遍历数十亿行时节省几毫秒的时间,并且数组的长度在整个过程中不会改变,那么你可以考虑在for循环中缓存长度。虽然我认为现在这个做法真的没有必要:
for (var i = 0, len = arr.length; i < len; i++) { // Do stuff with arr[i] }
这里还提到了一些其他测试的结果,但是这些测试和通常的场景有所不同,所以结果也不一样。一些测试还发现,如果你使用类似`for(let i=0, j=array.length; i < j; i++)`这样的零基准缓存for循环,正向for循环的速度会显著加快。在我的一些测试中,它是最快的,大多数情况下与逆向循环的结果相差无几。
最终的结论是,使用直接的for循环是最快的方式。然而,对于小规模的迭代或者可读性要求较高的情况,使用forEach回调函数也是一个不错的选择。
(注:以上内容根据提供的信息进行整理,可能不完全准确)
问题的出现原因:在JavaScript中循环遍历数组时,有很多不同的方法可以使用。这里有一个关于使用while循环遍历数组的方法,但是有一些人对此方法的效率提出了不同的意见,并提供了其他方法来进行比较。
解决方法:根据提供的链接和建议,我们可以通过使用for循环来获得更高的效率。这是一个普遍认可的解决方法,即使在不同的浏览器中,它也比使用while循环更快。此外,我们还可以在代码中使用var关键字来声明变量,以避免变量成为全局变量。
以下是整理后的
JavaScript中循环遍历数组的最快方法是什么?
在JavaScript中,我们经常需要对数组进行循环遍历。有很多不同的方法可以做到这一点,但是哪种方法是最快的呢?让我们来看看一个方法,然后将其与其他方法进行比较。
在一个帖子中,某些情况下了一种使用while循环来遍历数组的方法。代码如下:
var len = arr.length; while (len--) { // do something }
这种方法是否真的是最快的呢?有人对此提出了不同的意见,并提供了更多的循环性能比较数据。根据这些比较数据,使用for循环可能会比使用while循环更快。这是一个被广泛认可的解决方法,即使在不同的浏览器中也是如此。
另外,我们还需要注意,在代码中使用var关键字来声明变量。这样做可以避免变量成为全局变量,从而提高代码的可读性和维护性。
如果你对以上方法还有疑问,可以参考下面的链接获取更多的循环性能比较数据:
[jsperf.com/loops](http://jsperf.com/loops)
总之,使用for循环来遍历数组是最快的方法。这是一个被广泛认可的最佳实践,即使在不同的浏览器中也是如此。不要忘记在代码中使用var关键字来声明变量,以避免变量成为全局变量。如果你对这个问题还有疑问,可以参考上面提供的链接获取更多的信息。
希望这篇文章对你有所帮助!
什么是在JavaScript中循环遍历数组的最快方法?
在进行了与大多数现代浏览器的测试之后:
https://jsben.ch/wY5fo
目前,最快的循环形式(并且在我看来是最语法明显的)是标准的for循环,带有长度缓存:
var i = 0, len = myArray.length; while (i < len) { // your code i++ }
我必须说,这绝对是我对JavaScript引擎开发者的赞扬之处。运行时应该针对清晰度进行优化,而不是聪明。
有趣的是,在IE9中,这个循环更快:
for (var i = 0, len = myArray.length; i < len; ++i) {}
参见“Prefer prefix operators over postfix”以了解使用++i的其他原因。
我按照建议使用前缀运算符进行了测试,运行速度稍快:
for(var i=0, len=myArray.length; i<len; ++i)
请参阅jsperf.com/caching-array-length/84
在使用这个循环时,你必须小心。我开始使用它,并因为一个错误而遇到了很难追踪的错误。如果你像这样嵌套两个循环:
jsfiddle.net/KQwmL/1
你必须小心在两个循环中为变量len命名,否则第二个循环将覆盖第一个len。
为什么没有使用“var len = myArray.length”来缓存长度,这样不是就避免了作用域冲突吗?
你可以使用单个var语句声明多个变量。按照现在的写法,len实际上是按照你的建议进行了作用域限定。
哦,当然,我经常在对象的顶部这样做。谢谢!
那个jsPerf链接失效了,这是另一个链接:jsperf.com/array-length-vs-cached
性能上的差异似乎微不足道。这是否值得以牺牲可读性和细微逻辑错误的方式?如果数组在循环中被修改,并且你实际上对数组的长度感兴趣,那么这样的错误会耗费很多的编程时间。
这个答案是错误的。来源:stackoverflow.com/questions/1340589/…
你错了。来源:stackoverflow.com/a/7252102/555384。好吧,说真的,这个答案所基于的博客已经有6年了,你不认为JS引擎的性能特性已经改变了吗?这已经成为我们时代的伟大竞赛。
实际上,如果你点击这个答案中链接的jsperf,你会发现while循环要快得多。这个答案选择了第二快(并且要慢得多的)循环,因为“它最明显地符合语法”。问题是问题问的是什么是最快的循环,而不是最快的循环,看起来“在语法上明显”是什么意思。
那不是最快的方式 -_-
与此相关,使用for(var o in Object)的性能和差异如何?
似乎“while”有时会很有用:jsperf.com/fastest-array-loops-in-javascript/32
“for of”循环方法仅比索引方法稍慢,但有时更清晰:jsben.ch/ervtW
“运行时应该优化为清晰,而不是聪明”。你能解释一下清晰相对于聪明的优势是什么吗?此外,这不是影响程序行为的优化。
jsben.ch/cMAc2 改进了测试用例,添加了forEach进行比较
我们可以使用过滤器和映射来遍历数组,速度看起来更快:stackoverflow.com/questions/5349425/…
另外,最好是将长度保存到一个变量中,而不是在每次循环迭代中进行检查。
使用while关键字编写的“for循环”如何“优化为清晰”?
现在是2021年了,这还有效吗?map等函数呢?
这将始终有效。任何语言中都不存在更有效的表达式。从技术上讲,使用前缀运算符++i(使用前缀运算符)更快,因为它可以避免计算机复制整数(请注意,对于这样的小整数,这永远不会有任何区别)。对于map这样的问题,函数式模式几乎总是更慢的。在map的情况下,所有对象都必须被复制。仅仅这样一个迭代本身,像forEach一样,比for或while循环要慢得多。创建函数闭包和复制参数也会减慢这种用法。
这个答案可能已经过时了,考虑支持更近期的答案。
这个答案提倡使用for循环,然而却以while循环为例。
但这是一个while循环,而不是for循环,对吗?你说的是for循环,然后继续使用while循环?