JavaScript 中最快的循环是什么?

无论使用哪种编程语言,循环都是一种内置功能。JavaScript 也不例外,它提供了多种实现循环的方法,偶尔会给开发人员带来困惑:哪一种循环才是最快的?

以下是Javascript中可以实现循环的方法:

  • For Loop
  • While Loop
  • Do-While Loop
  • For-In Loop
  • For-Of Loop
  • ForEach Loop
  • Map Loop
  • Filter Loop
  • Reduce Loop
  • Some Loop
  • Every Loop
  • Find Loop

我们将对这些循环方法进行测试,以确定哪种方法最快。

为了比较每个循环的性能,我们将使用 console.time() 和 console.timeEnd() 方法来测量它们的执行时间。

javascript 复制代码
console.time('My Description');

// Code to measure

console.timeEnd('My Description');

用于测试的任务是:将 5000 万个项目从一个数组转移到另一个数组。

javascript 复制代码
console.time('Array Creation');
  
const numbersList = Array.from({ length: 50_000_000 }, () => Math.floor(Math.random() * 100));

console.timeEnd('Array Creation');

为确保公平比较,我们将异步运行每个循环。

虽然 For-In 的语法与 For-Of 类似,但它不是为数组设计的,因此不在测试之中。 For-In 更适合迭代具有多个属性的对象,因为它迭代的是属性名称(或键)而不是值本身,而与数组一起使用会导致性能问题和意外行为。

scss 复制代码
(async () => {
  await usingForLoop(numbersList);
  await usingWhile(numbersList);
  await usingDoWhile(numbersList);
  await usingForOf(numbersList);
  await usingForEach(numbersList);
  await usingMap(numbersList);
  await usingFilter(numbersList);
  await usingReduce(numbersList);
  await usingSome(numbersList);
  await usingEvery(numbersList);
  await usingFind(numbersList);
})()

ForLoop

ini 复制代码
const usingForLoop = async (array) => {
  console.time('FOR LOOP');

  const newNumbersList = [];
  for (let i = 0; i < array.length; i++) {
    newNumbersList.push(array[i]);
  }

  console.timeEnd('FOR LOOP');
}

while

ini 复制代码
const usingWhile = async (array) => {
 console.time('WHILE');

 let i = 0;
 const newNumbersList = [];
 while (i < array.length) {
   newNumbersList.push(array[i]);
   i++;
 }

 console.timeEnd('WHILE');
}

doWhile

ini 复制代码
const usingDoWhile = async (array) => {
 console.time('DO WHILE');

 let i = 0;
 const newNumbersList = [];
 do {
   newNumbersList.push(array[i]);
   i++;
 } while (i < array.length);

 console.timeEnd('DO WHILE');
}

ForOf

javascript 复制代码
const usingForOf = async (array) => {
  console.time('FOR OF');

  const newNumbersList = [];
  for (const item of array) {
    newNumbersList.push(item);
  }

  console.timeEnd('FOR OF');
}

ForEach

javascript 复制代码
const usingForEach = async (array) => {
  console.time('FOR EACH');

  const newNumbersList = [];
  array.forEach((item) => newNumbersList.push(item));

  console.timeEnd('FOR EACH');
}

Map

typescript 复制代码
const usingMap = async (array) => {
 console.time('MAP');

 const newNumbersList = array.map((number) => number);

 console.timeEnd('MAP');
}

Filer

javascript 复制代码
const usingFilter = async (array) => {
 console.time('FILTER');

 const newNumbersList = array.filter((item) => true);

 console.timeEnd('FILTER');
}

Reduce

javascript 复制代码
const usingReduce = async (array) => {
 console.time('REDUCE');

 const newNumbersList = array.reduce((acc, item) => {
   acc.push(item);
   return acc;
 }, []);

 console.timeEnd('REDUCE');
}

Some

javascript 复制代码
const usingSome = async (array) => {
 console.time('SOME');

 const newNumbersList = [];
 array.some((item) => {
   newNumbersList.push(item);
   return false;
 });

 console.timeEnd('SOME')
}

Every

javascript 复制代码
const usingEvery = async (array) => {
  console.time('EVERY');

  const newNumbersList = [];
  array.every((item) => {
    newNumbersList.push(item);
    return true;
  });

  console.timeEnd('EVERY')
}

Find

javascript 复制代码
const usingFind = async (array) => {
  console.time('FIND');

  const newNumbersList= [];
  array.find((item) => {
    newNumbersList.push(item);
    return false;
  });

  console.timeEnd('FIND')
}

任务运行了五次,显示的测量值是计算得出的平均值。

测试平均结果如下:

从结果可以看出,前5名分别是:

    1. Map
    1. For Loop
    1. While
    1. Do While
    1. For Each

有趣的是只有Map是一个函数调用,其余的都是循环体。

另外该测试仅针对一项特定任务进行的,不同测试用例可能会有不同的结果,不同的内存或者CPU也会有不一样的表现。从本次测试的结果,我们可以看到Map 和 For Loop 的性能是最好的。令人失望的是For-Of,相对于For Loop,作为新出的一个API竟然效率这么拉跨。

Map每次循环都需要调用回调函数,理论上不应该比For Loop更快。但现代 JavaScript 引擎(如 V8)对高阶函数(如 map、filter 等)进行了高度优化,尤其是对数组的处理。引擎内部可能会针对这些高阶函数应用特定的优化策略,减少不必要的操作,进而提升性能。而且 map 是一个专门用于遍历数组并返回新数组的高阶函数,V8 等引擎能够更好地预测和优化其内部的操作路径。而 for loop 是更通用的控制结构,可能没有这些特定的优化。

结论

从测试结果看Map和For Loop的循环效率相差不大,大家可以根据需要做选择。map 无法中途退出,但可以返回一个新的数组。

相关推荐
辻戋2 小时前
从零实现React Scheduler调度器
前端·react.js·前端框架
徐同保2 小时前
使用yarn@4.6.0装包,项目是react+vite搭建的,项目无法启动,报错:
前端·react.js·前端框架
Qrun3 小时前
Windows11安装nvm管理node多版本
前端·vscode·react.js·ajax·npm·html5
中国lanwp3 小时前
全局 npm config 与多环境配置
前端·npm·node.js
JELEE.4 小时前
Django登录注册完整代码(图片、邮箱验证、加密)
前端·javascript·后端·python·django·bootstrap·jquery
TeleostNaCl6 小时前
解决 Chrome 无法访问网页但无痕模式下可以访问该网页 的问题
前端·网络·chrome·windows·经验分享
前端大卫7 小时前
为什么 React 中的 key 不能用索引?
前端
你的人类朋友7 小时前
【Node】手动归还主线程控制权:解决 Node.js 阻塞的一个思路
前端·后端·node.js
小李小李不讲道理9 小时前
「Ant Design 组件库探索」五:Tabs组件
前端·react.js·ant design
毕设十刻9 小时前
基于Vue的学分预警系统98k51(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js