Bootstrap

for、forEach的执行效率,怎样优化响应速度

百度了一些文献,说法都很片面,只讲了for循环的执行效率要优于其它数组方法,实际检验中并非如此。

参考了百度AI的回答,对数组方法的底层原理有了新的认识

由此可知:forEach虽然语法简洁,代码可读性高,但底层实现需要进行函数调用和内存分配。在处理大数据时,由于函数调用的开销,性能会差一些。 

实验目的: 声明一个数组和一个空的方法,从100、1万、100万的量级来逐步分析,判断不同循环执行效率的优差

实验开始:

  // 声明一个百条数组
  let source = new Array(100).fill(1).map((i, index) => index + 1)
  console.log(source, 'source');

  // 一个空的方法
  function func(item, index, arr) {
    
  }
  
  // for循环
  console.time('for')
  for(let index = 0; index < source.length; index++) {
    func(source[index], index, source)
  }
  console.timeEnd('for')
  
  // forEach
  console.time('forEach')
  source.forEach((item, index) => func(item, index, source))
  console.timeEnd('forEach')

每次执行完毕所需要的时间不是固定的,根据电脑执行js脚本的快慢会占用不同的时长 

但明显可以看出, forEach的执行效率要优于传统for循环 

在写法上来说, forEach还具备进一步优化的空间

source.forEach(func)
source.forEach((item, index) => func(item, index, source))

这两段代码的执行结果没有任何差别, 第二段之所以用时更长,可能是因为箭头函数的性能以及可能的作用域问题,包括函数调用开销等,理论上会比第一段调用的栈多。

而第一段func 是直接作为参数传递给 forEach 方法的。func 是一个已经定义好的函数,这里几乎没有额外函数调用的开销。

接下来我们把量级提升到1万,看一下for、forEach、map、filter的表现

在这样的量级面前,可以看出for循环的执行效率依然弱于常用的数组方法,而且 forEach的表现还是很不错的

那来测试一下百万量级,看看他们的表现有没有变化

 

经过两次的比较,for循环的表现有些出人意料,传统for循环在庞大的数据量级之下,执行效率要优于大多数方法,而且是断崖式领先。

原因可能在于:

forEach方法内部为每个数组元素调用一次提供的回调函数。这意味着对于数组中的每个元素,都会有一次额外的函数调用开销。在庞大的数组上,这些开销会累积起来,导致性能下降。

而传统的for循环则没有这种额外的函数调用开销,因为它直接在循环体内执行所需的逻辑,而不需要通过额外的函数调用。

forEach中使用的回调函数可能会创建闭包,特别是当回调函数内部访问外部作用域中的变量时。闭包会增加内存使用和处理时间,因为每次迭代都可能需要创建新的闭包环境。

现代JavaScript引擎对for循环进行了高度优化,能够识别并优化简单的迭代模式。这些优化可能包括减少不必要的内存分配、提高循环控制语句的执行速度等。

forEach方法虽然也被优化,但由于其基于函数调用的特性,优化程度可能不如传统的for循环。

传统的for循环允许在循环体内的任何位置使用breakcontinuereturn语句来终止迭代或跳过某些元素。而forEach则不提供这样的功能。

那么在项目中应该根据数据的体量和对项目的考量进行综合判断,搭配使用各种循环语句,而不是偏执的认为某一种循环一定是最优方案,这是不对的。

;