探究前端中各种循环的执行性能


一、探究背景

近期,工作项目没有那么忙碌了,就对项目组前端的规范进行了重新的审视和修订。其中涉及到有一条,就是如何选定合适的循环方式进行循环。这其中要考虑到性能及所处的场景以及用途。下面我们来一探究竟吧。

二、前端中存在的各种循环

const shapes = ['cicle', 'triangle', 'square', 'ellipse']

常见for循环有:

  1. 普通版for循环【即不带声明的for循环】

    for (let i = 0; i < shapes.length; i++) {
      console.log(shapes[i])
    }
  2. 优化版for循环 【即带声明的for循环】
    将shapes.length缓存到变量len中,这样每次循环时就不会再读取数组的长度。当数组较大时优化效果才较明显。

    for (let i = 0, len = shapes.length; i < len; i++) {
       console.log(shapes[i])
    }
  3. 变形for循环(一)
    将取值与判断合并,通过不停的枚举每一项来循环,直到枚举到空值则循环结束。执行顺序是:
    第一步:先声明索引i = 0和变量shape
    第二步:取出数组的第i项shapes[i]赋值给变量person并判断是否为Truthy
    第三步:执行循环体,打印shape
    第四步:i++

    for (let i = 0, shape; shape = shapes[i]; i++) {
       console.log(shape)
    }
  4. 变形for循环(二)
    第一步:获取数组长度,赋值给变量i
    第二步:判断i是否大于0并执行i--
    第三步:执行循环体,打印persons[i],此时的i已经-1了
    从后向前,直到 i === 0为止。这种方式不仅去除了每次循环中读取数组长度的操作,而且只创建了一个变量 i。

    for (let i = shapes.length; i--;) {
      console.log(shapes[i])
    }
  5. forEach
  6. map
  7. some
  8. filter
  9. for...of

三、我们通过测试方法进行性能测试

首先我们创建包含40000000条数字的数组,然后在通过相应几种循环方式进行对比。这里主要对比

  1. forEach循环
  2. 带变量声明的for循环
  3. 不带变量声明的for循环
  4. map循环

我们分别通过,整体循环20次,50次,100次,分别统计各种方式循环所需时间的平均值,并进行比较。

// 创建用于测试的数组,共含40000000条数据。
var testArrs = [],
  i = 0;
while (i < 40000000) {
  testArrs.push(i);
  i++;
}

document.write("Creat an Array, includes 40000000 items<br/><br/>");

// forEach测试用例
function testForeach(testArrs) {
  console.time("Foreach:");
  var start = Date.now();
  var newArrs = [];
  testArrs.forEach(function (i) {
    newArrs.push(i);
  });
  console.timeEnd("Foreach:");
  var end = Date.now();
  document.write("【Foreach:" + (end - start) + "ms】");
  return end - start;
}

// 不带声明的for循环测试用例
function testNoDeclare(testArrs) {
  console.time("No declare:");
  var start = Date.now();
  var newArrs = [];
  for (var i = 0; i < testArrs.length; i++) {
    newArrs.push(i);
  }
  console.timeEnd("No declare:");
  var end = Date.now();
  document.write("【No declare:" + (end - start) + "ms】");
  return end - start;
}

// 带声明的for循环测试用例
function testUseDeclare(testArrs) {
  console.time("Use declare:");
  var start = Date.now();
  var newArrs = [];
  for (var i = 0, len = testArrs.length; i < len; i++) {
    newArrs.push(i);
  }
  console.timeEnd("Use declare:");
  var end = Date.now();
  document.write("【Use declare:" + (end - start) + "ms】");
  return end - start;
}

// map循环测试用例
function testMap(testArrs) {
  console.time("Map:");
  var start = Date.now();
  var newArrs = [];
  testArrs.map((item) => {
    newArrs.push(item);
  });
  console.timeEnd("Map:");
  var end = Date.now();
  document.write("【Map:" + (end - start) + "ms】");
  return end - start;
}

var [foreachSum, nodeclareSum, usedeclareSum, mapSum] = [0, 0, 0, 0];
// 进行n次循环测试
var loopTotal = 100;
for (var i = loopTotal; i--; ) {
  document.write(`第${loopTotal - i}次:`);
  foreachSum += testForeach(testArrs);
  nodeclareSum += testNoDeclare(testArrs);
  usedeclareSum += testUseDeclare(testArrs);
  mapSum += testMap(testArrs);
  document.write(
    "<br/>----------------------------------------------------------------------<br/>"
  );
}

// 统计相应的循环方法的平均消耗时间
var meanTimeForeach = foreachSum / loopTotal;
var meanTimeNoDeclare = nodeclareSum / loopTotal;
var meanTimeUseDeclare = usedeclareSum / loopTotal;
var meanTimeMap = mapSum / loopTotal;
var list = [
  { time: meanTimeForeach, name: "Foreach" },
  { time: meanTimeNoDeclare, name: "No declare" },
  { time: meanTimeUseDeclare, name: "Use declare" },
  { time: meanTimeMap, name: "Map" },
];

// 做排序,并输出
var result = list.sort(function (a, b) {
  return a.time - b.time;
});
document.write("<br/>Mean time rank:");
for (var i = 0; i < result.length; i++) {
  document.write(`【${result[i].name}:${result[i].time}ms】`);
}

四、展示对比各种循环方式的测试结果

【20次循环测试对比】
Creat an Array, includes 40000000 items
 
第1次:【Foreach:835ms】【No declare:541ms】【Use declare:472ms】【Map:1330ms】
----------------------------------------------------------------------
第2次:【Foreach:826ms】【No declare:390ms】【Use declare:578ms】【Map:1068ms】
----------------------------------------------------------------------
第3次:【Foreach:978ms】【No declare:330ms】【Use declare:483ms】【Map:1085ms】
----------------------------------------------------------------------
第4次:【Foreach:1058ms】【No declare:369ms】【Use declare:501ms】【Map:1187ms】
----------------------------------------------------------------------
第5次:【Foreach:780ms】【No declare:460ms】【Use declare:344ms】【Map:1164ms】
----------------------------------------------------------------------
第6次:【Foreach:792ms】【No declare:471ms】【Use declare:348ms】【Map:1208ms】
----------------------------------------------------------------------
第7次:【Foreach:798ms】【No declare:474ms】【Use declare:336ms】【Map:1267ms】
----------------------------------------------------------------------
第8次:【Foreach:838ms】【No declare:469ms】【Use declare:335ms】【Map:1227ms】
----------------------------------------------------------------------
第9次:【Foreach:809ms】【No declare:486ms】【Use declare:320ms】【Map:1226ms】
----------------------------------------------------------------------
第10次:【Foreach:809ms】【No declare:475ms】【Use declare:358ms】【Map:1166ms】
----------------------------------------------------------------------
第11次:【Foreach:852ms】【No declare:474ms】【Use declare:351ms】【Map:1209ms】
----------------------------------------------------------------------
第12次:【Foreach:830ms】【No declare:470ms】【Use declare:343ms】【Map:1228ms】
----------------------------------------------------------------------
第13次:【Foreach:804ms】【No declare:491ms】【Use declare:358ms】【Map:1201ms】
----------------------------------------------------------------------
第14次:【Foreach:792ms】【No declare:467ms】【Use declare:333ms】【Map:1183ms】
----------------------------------------------------------------------
第15次:【Foreach:826ms】【No declare:497ms】【Use declare:334ms】【Map:1192ms】
----------------------------------------------------------------------
第16次:【Foreach:792ms】【No declare:470ms】【Use declare:337ms】【Map:1223ms】
----------------------------------------------------------------------
第17次:【Foreach:803ms】【No declare:488ms】【Use declare:341ms】【Map:1212ms】
----------------------------------------------------------------------
第18次:【Foreach:804ms】【No declare:490ms】【Use declare:341ms】【Map:1219ms】
----------------------------------------------------------------------
第19次:【Foreach:835ms】【No declare:477ms】【Use declare:345ms】【Map:1207ms】
----------------------------------------------------------------------
第20次:【Foreach:796ms】【No declare:486ms】【Use declare:358ms】【Map:1271ms】
----------------------------------------------------------------------
 
Mean time rank:【Use declare:375.8ms】【No declare:463.75ms】【Foreach:832.85ms】【Map:1203.65ms】
 
【50次循环测试对比】
Creat an Array, includes 40000000 items
 
第1次:【Foreach:1082ms】【No declare:401ms】【Use declare:474ms】【Map:1359ms】
----------------------------------------------------------------------
第2次:【Foreach:814ms】【No declare:318ms】【Use declare:556ms】【Map:1123ms】
----------------------------------------------------------------------
第3次:【Foreach:984ms】【No declare:579ms】【Use declare:302ms】【Map:1054ms】
----------------------------------------------------------------------
第4次:【Foreach:977ms】【No declare:346ms】【Use declare:491ms】【Map:1264ms】
----------------------------------------------------------------------
第5次:【Foreach:735ms】【No declare:406ms】【Use declare:506ms】【Map:1061ms】
----------------------------------------------------------------------
第6次:【Foreach:957ms】【No declare:371ms】【Use declare:473ms】【Map:1160ms】
----------------------------------------------------------------------
第7次:【Foreach:793ms】【No declare:468ms】【Use declare:365ms】【Map:1186ms】
----------------------------------------------------------------------
第8次:【Foreach:802ms】【No declare:473ms】【Use declare:357ms】【Map:1215ms】
----------------------------------------------------------------------
第9次:【Foreach:820ms】【No declare:494ms】【Use declare:395ms】【Map:1433ms】
----------------------------------------------------------------------
第10次:【Foreach:786ms】【No declare:465ms】【Use declare:324ms】【Map:1198ms】
----------------------------------------------------------------------
第11次:【Foreach:796ms】【No declare:464ms】【Use declare:329ms】【Map:1294ms】
----------------------------------------------------------------------
第12次:【Foreach:850ms】【No declare:493ms】【Use declare:396ms】【Map:1366ms】
----------------------------------------------------------------------
第13次:【Foreach:1361ms】【No declare:548ms】【Use declare:467ms】【Map:1304ms】
----------------------------------------------------------------------
第14次:【Foreach:904ms】【No declare:574ms】【Use declare:802ms】【Map:1367ms】
----------------------------------------------------------------------
第15次:【Foreach:1903ms】【No declare:635ms】【Use declare:986ms】【Map:2585ms】
----------------------------------------------------------------------
第16次:【Foreach:1754ms】【No declare:814ms】【Use declare:841ms】【Map:2648ms】
----------------------------------------------------------------------
第17次:【Foreach:1283ms】【No declare:521ms】【Use declare:372ms】【Map:1554ms】
----------------------------------------------------------------------
第18次:【Foreach:983ms】【No declare:552ms】【Use declare:418ms】【Map:1515ms】
----------------------------------------------------------------------
第19次:【Foreach:1081ms】【No declare:618ms】【Use declare:441ms】【Map:1306ms】
----------------------------------------------------------------------
第20次:【Foreach:919ms】【No declare:511ms】【Use declare:411ms】【Map:1259ms】
----------------------------------------------------------------------
第21次:【Foreach:902ms】【No declare:578ms】【Use declare:444ms】【Map:1413ms】
----------------------------------------------------------------------
第22次:【Foreach:1090ms】【No declare:593ms】【Use declare:483ms】【Map:1453ms】
----------------------------------------------------------------------
第23次:【Foreach:1213ms】【No declare:803ms】【Use declare:528ms】【Map:1928ms】
----------------------------------------------------------------------
第24次:【Foreach:1200ms】【No declare:739ms】【Use declare:516ms】【Map:1369ms】
----------------------------------------------------------------------
第25次:【Foreach:945ms】【No declare:514ms】【Use declare:373ms】【Map:1248ms】
----------------------------------------------------------------------
第26次:【Foreach:867ms】【No declare:508ms】【Use declare:389ms】【Map:1236ms】
----------------------------------------------------------------------
第27次:【Foreach:853ms】【No declare:488ms】【Use declare:347ms】【Map:1246ms】
----------------------------------------------------------------------
第28次:【Foreach:829ms】【No declare:499ms】【Use declare:368ms】【Map:1301ms】
----------------------------------------------------------------------
第29次:【Foreach:825ms】【No declare:775ms】【Use declare:616ms】【Map:1664ms】
----------------------------------------------------------------------
第30次:【Foreach:2153ms】【No declare:654ms】【Use declare:552ms】【Map:2114ms】
----------------------------------------------------------------------
第31次:【Foreach:976ms】【No declare:799ms】【Use declare:385ms】【Map:1538ms】
----------------------------------------------------------------------
第32次:【Foreach:943ms】【No declare:506ms】【Use declare:505ms】【Map:1673ms】
----------------------------------------------------------------------
第33次:【Foreach:1256ms】【No declare:524ms】【Use declare:401ms】【Map:1347ms】
----------------------------------------------------------------------
第34次:【Foreach:814ms】【No declare:501ms】【Use declare:350ms】【Map:1286ms】
----------------------------------------------------------------------
第35次:【Foreach:905ms】【No declare:498ms】【Use declare:368ms】【Map:1254ms】
----------------------------------------------------------------------
第36次:【Foreach:866ms】【No declare:512ms】【Use declare:383ms】【Map:1240ms】
----------------------------------------------------------------------
第37次:【Foreach:965ms】【No declare:574ms】【Use declare:452ms】【Map:1462ms】
----------------------------------------------------------------------
第38次:【Foreach:943ms】【No declare:521ms】【Use declare:404ms】【Map:1271ms】
----------------------------------------------------------------------
第39次:【Foreach:898ms】【No declare:523ms】【Use declare:386ms】【Map:1232ms】
----------------------------------------------------------------------
第40次:【Foreach:803ms】【No declare:504ms】【Use declare:350ms】【Map:1220ms】
----------------------------------------------------------------------
第41次:【Foreach:803ms】【No declare:496ms】【Use declare:361ms】【Map:1231ms】
----------------------------------------------------------------------
第42次:【Foreach:847ms】【No declare:505ms】【Use declare:374ms】【Map:1204ms】
----------------------------------------------------------------------
第43次:【Foreach:842ms】【No declare:492ms】【Use declare:375ms】【Map:1210ms】
----------------------------------------------------------------------
第44次:【Foreach:820ms】【No declare:513ms】【Use declare:328ms】【Map:1300ms】
----------------------------------------------------------------------
第45次:【Foreach:809ms】【No declare:505ms】【Use declare:351ms】【Map:1237ms】
----------------------------------------------------------------------
第46次:【Foreach:847ms】【No declare:488ms】【Use declare:346ms】【Map:1223ms】
----------------------------------------------------------------------
第47次:【Foreach:833ms】【No declare:500ms】【Use declare:347ms】【Map:1231ms】
----------------------------------------------------------------------
第48次:【Foreach:834ms】【No declare:484ms】【Use declare:336ms】【Map:1236ms】
----------------------------------------------------------------------
第49次:【Foreach:857ms】【No declare:494ms】【Use declare:326ms】【Map:1243ms】
----------------------------------------------------------------------
第50次:【Foreach:843ms】【No declare:520ms】【Use declare:390ms】【Map:1194ms】
----------------------------------------------------------------------
 
Mean time rank:【Use declare:436.8ms】【No declare:533.22ms】【Foreach:983.3ms】【Map:1381.1ms】
 
【100次循环测试对比】
Creat an Array, includes 40000000 items
 
第1次:【Foreach:796ms】【No declare:356ms】【Use declare:511ms】【Map:1004ms】
----------------------------------------------------------------------
第2次:【Foreach:917ms】【No declare:330ms】【Use declare:365ms】【Map:1020ms】
----------------------------------------------------------------------
第3次:【Foreach:819ms】【No declare:519ms】【Use declare:357ms】【Map:1195ms】
----------------------------------------------------------------------
第4次:【Foreach:901ms】【No declare:525ms】【Use declare:357ms】【Map:1346ms】
----------------------------------------------------------------------
第5次:【Foreach:884ms】【No declare:685ms】【Use declare:346ms】【Map:1183ms】
----------------------------------------------------------------------
第6次:【Foreach:788ms】【No declare:469ms】【Use declare:332ms】【Map:1211ms】
----------------------------------------------------------------------
第7次:【Foreach:951ms】【No declare:506ms】【Use declare:359ms】【Map:1265ms】
----------------------------------------------------------------------
第8次:【Foreach:790ms】【No declare:469ms】【Use declare:341ms】【Map:1170ms】
----------------------------------------------------------------------
第9次:【Foreach:779ms】【No declare:468ms】【Use declare:323ms】【Map:1179ms】
----------------------------------------------------------------------
第10次:【Foreach:802ms】【No declare:513ms】【Use declare:327ms】【Map:2078ms】
----------------------------------------------------------------------
第11次:【Foreach:1453ms】【No declare:564ms】【Use declare:1377ms】【Map:2364ms】
----------------------------------------------------------------------
第12次:【Foreach:3707ms】【No declare:849ms】【Use declare:509ms】【Map:1339ms】
----------------------------------------------------------------------
第13次:【Foreach:845ms】【No declare:495ms】【Use declare:344ms】【Map:1202ms】
----------------------------------------------------------------------
第14次:【Foreach:778ms】【No declare:469ms】【Use declare:317ms】【Map:1173ms】
----------------------------------------------------------------------
第15次:【Foreach:768ms】【No declare:466ms】【Use declare:348ms】【Map:1149ms】
----------------------------------------------------------------------
第16次:【Foreach:792ms】【No declare:475ms】【Use declare:342ms】【Map:1166ms】
----------------------------------------------------------------------
第17次:【Foreach:816ms】【No declare:473ms】【Use declare:336ms】【Map:1190ms】
----------------------------------------------------------------------
第18次:【Foreach:780ms】【No declare:466ms】【Use declare:326ms】【Map:1183ms】
----------------------------------------------------------------------
第19次:【Foreach:812ms】【No declare:466ms】【Use declare:319ms】【Map:1186ms】
----------------------------------------------------------------------
第20次:【Foreach:810ms】【No declare:464ms】【Use declare:322ms】【Map:1183ms】
----------------------------------------------------------------------
第21次:【Foreach:807ms】【No declare:468ms】【Use declare:323ms】【Map:1163ms】
----------------------------------------------------------------------
第22次:【Foreach:819ms】【No declare:479ms】【Use declare:298ms】【Map:1178ms】
----------------------------------------------------------------------
第23次:【Foreach:789ms】【No declare:466ms】【Use declare:339ms】【Map:1145ms】
----------------------------------------------------------------------
第24次:【Foreach:796ms】【No declare:493ms】【Use declare:332ms】【Map:1226ms】
----------------------------------------------------------------------
第25次:【Foreach:805ms】【No declare:479ms】【Use declare:331ms】【Map:1195ms】
----------------------------------------------------------------------
第26次:【Foreach:786ms】【No declare:478ms】【Use declare:301ms】【Map:1201ms】
----------------------------------------------------------------------
第27次:【Foreach:879ms】【No declare:476ms】【Use declare:340ms】【Map:1152ms】
----------------------------------------------------------------------
第28次:【Foreach:783ms】【No declare:477ms】【Use declare:325ms】【Map:1191ms】
----------------------------------------------------------------------
第29次:【Foreach:817ms】【No declare:463ms】【Use declare:324ms】【Map:1187ms】
----------------------------------------------------------------------
第30次:【Foreach:777ms】【No declare:466ms】【Use declare:324ms】【Map:1180ms】
----------------------------------------------------------------------
第31次:【Foreach:777ms】【No declare:471ms】【Use declare:323ms】【Map:1191ms】
----------------------------------------------------------------------
第32次:【Foreach:783ms】【No declare:475ms】【Use declare:349ms】【Map:1191ms】
----------------------------------------------------------------------
第33次:【Foreach:794ms】【No declare:473ms】【Use declare:359ms】【Map:1202ms】
----------------------------------------------------------------------
第34次:【Foreach:804ms】【No declare:477ms】【Use declare:334ms】【Map:1183ms】
----------------------------------------------------------------------
第35次:【Foreach:782ms】【No declare:479ms】【Use declare:336ms】【Map:1199ms】
----------------------------------------------------------------------
第36次:【Foreach:807ms】【No declare:465ms】【Use declare:320ms】【Map:1206ms】
----------------------------------------------------------------------
第37次:【Foreach:813ms】【No declare:487ms】【Use declare:328ms】【Map:1379ms】
----------------------------------------------------------------------
第38次:【Foreach:850ms】【No declare:488ms】【Use declare:340ms】【Map:1249ms】
----------------------------------------------------------------------
第39次:【Foreach:801ms】【No declare:563ms】【Use declare:346ms】【Map:1218ms】
----------------------------------------------------------------------
第40次:【Foreach:794ms】【No declare:481ms】【Use declare:336ms】【Map:1176ms】
----------------------------------------------------------------------
第41次:【Foreach:792ms】【No declare:474ms】【Use declare:322ms】【Map:1186ms】
----------------------------------------------------------------------
第42次:【Foreach:780ms】【No declare:468ms】【Use declare:323ms】【Map:1192ms】
----------------------------------------------------------------------
第43次:【Foreach:794ms】【No declare:475ms】【Use declare:332ms】【Map:1192ms】
----------------------------------------------------------------------
第44次:【Foreach:780ms】【No declare:477ms】【Use declare:331ms】【Map:1221ms】
----------------------------------------------------------------------
第45次:【Foreach:803ms】【No declare:483ms】【Use declare:367ms】【Map:1167ms】
----------------------------------------------------------------------
第46次:【Foreach:815ms】【No declare:463ms】【Use declare:330ms】【Map:1181ms】
----------------------------------------------------------------------
第47次:【Foreach:781ms】【No declare:486ms】【Use declare:332ms】【Map:1214ms】
----------------------------------------------------------------------
第48次:【Foreach:801ms】【No declare:483ms】【Use declare:319ms】【Map:1193ms】
----------------------------------------------------------------------
第49次:【Foreach:774ms】【No declare:465ms】【Use declare:330ms】【Map:1193ms】
----------------------------------------------------------------------
第50次:【Foreach:778ms】【No declare:481ms】【Use declare:326ms】【Map:1190ms】
----------------------------------------------------------------------
第51次:【Foreach:812ms】【No declare:492ms】【Use declare:331ms】【Map:1198ms】
----------------------------------------------------------------------
第52次:【Foreach:781ms】【No declare:463ms】【Use declare:338ms】【Map:1185ms】
----------------------------------------------------------------------
第53次:【Foreach:812ms】【No declare:474ms】【Use declare:301ms】【Map:1175ms】
----------------------------------------------------------------------
第54次:【Foreach:775ms】【No declare:467ms】【Use declare:336ms】【Map:1159ms】
----------------------------------------------------------------------
第55次:【Foreach:880ms】【No declare:491ms】【Use declare:332ms】【Map:1218ms】
----------------------------------------------------------------------
第56次:【Foreach:772ms】【No declare:467ms】【Use declare:328ms】【Map:1187ms】
----------------------------------------------------------------------
第57次:【Foreach:783ms】【No declare:466ms】【Use declare:324ms】【Map:1227ms】
----------------------------------------------------------------------
第58次:【Foreach:837ms】【No declare:505ms】【Use declare:343ms】【Map:1204ms】
----------------------------------------------------------------------
第59次:【Foreach:836ms】【No declare:502ms】【Use declare:344ms】【Map:1252ms】
----------------------------------------------------------------------
第60次:【Foreach:830ms】【No declare:488ms】【Use declare:336ms】【Map:1215ms】
----------------------------------------------------------------------
第61次:【Foreach:786ms】【No declare:477ms】【Use declare:335ms】【Map:1234ms】
----------------------------------------------------------------------
第62次:【Foreach:787ms】【No declare:466ms】【Use declare:318ms】【Map:1195ms】
----------------------------------------------------------------------
第63次:【Foreach:835ms】【No declare:587ms】【Use declare:410ms】【Map:1224ms】
----------------------------------------------------------------------
第64次:【Foreach:804ms】【No declare:493ms】【Use declare:370ms】【Map:1262ms】
----------------------------------------------------------------------
第65次:【Foreach:873ms】【No declare:494ms】【Use declare:348ms】【Map:1246ms】
----------------------------------------------------------------------
第66次:【Foreach:830ms】【No declare:486ms】【Use declare:317ms】【Map:1189ms】
----------------------------------------------------------------------
第67次:【Foreach:763ms】【No declare:467ms】【Use declare:333ms】【Map:1153ms】
----------------------------------------------------------------------
第68次:【Foreach:779ms】【No declare:486ms】【Use declare:333ms】【Map:1198ms】
----------------------------------------------------------------------
第69次:【Foreach:806ms】【No declare:490ms】【Use declare:351ms】【Map:1235ms】
----------------------------------------------------------------------
第70次:【Foreach:839ms】【No declare:502ms】【Use declare:338ms】【Map:1227ms】
----------------------------------------------------------------------
第71次:【Foreach:801ms】【No declare:481ms】【Use declare:331ms】【Map:1223ms】
----------------------------------------------------------------------
第72次:【Foreach:834ms】【No declare:480ms】【Use declare:392ms】【Map:1303ms】
----------------------------------------------------------------------
第73次:【Foreach:836ms】【No declare:502ms】【Use declare:340ms】【Map:1223ms】
----------------------------------------------------------------------
第74次:【Foreach:812ms】【No declare:500ms】【Use declare:350ms】【Map:1223ms】
----------------------------------------------------------------------
第75次:【Foreach:787ms】【No declare:462ms】【Use declare:327ms】【Map:1164ms】
----------------------------------------------------------------------
第76次:【Foreach:790ms】【No declare:475ms】【Use declare:347ms】【Map:1226ms】
----------------------------------------------------------------------
第77次:【Foreach:805ms】【No declare:489ms】【Use declare:357ms】【Map:1228ms】
----------------------------------------------------------------------
第78次:【Foreach:808ms】【No declare:498ms】【Use declare:338ms】【Map:1177ms】
----------------------------------------------------------------------
第79次:【Foreach:811ms】【No declare:486ms】【Use declare:322ms】【Map:1210ms】
----------------------------------------------------------------------
第80次:【Foreach:766ms】【No declare:469ms】【Use declare:354ms】【Map:1190ms】
----------------------------------------------------------------------
第81次:【Foreach:831ms】【No declare:497ms】【Use declare:330ms】【Map:1215ms】
----------------------------------------------------------------------
第82次:【Foreach:828ms】【No declare:485ms】【Use declare:321ms】【Map:1203ms】
----------------------------------------------------------------------
第83次:【Foreach:807ms】【No declare:487ms】【Use declare:340ms】【Map:1208ms】
----------------------------------------------------------------------
第84次:【Foreach:830ms】【No declare:477ms】【Use declare:333ms】【Map:1226ms】
----------------------------------------------------------------------
第85次:【Foreach:824ms】【No declare:468ms】【Use declare:329ms】【Map:1209ms】
----------------------------------------------------------------------
第86次:【Foreach:994ms】【No declare:701ms】【Use declare:788ms】【Map:1526ms】
----------------------------------------------------------------------
第87次:【Foreach:892ms】【No declare:520ms】【Use declare:381ms】【Map:1261ms】
----------------------------------------------------------------------
第88次:【Foreach:866ms】【No declare:487ms】【Use declare:335ms】【Map:1214ms】
----------------------------------------------------------------------
第89次:【Foreach:808ms】【No declare:522ms】【Use declare:550ms】【Map:1301ms】
----------------------------------------------------------------------
第90次:【Foreach:917ms】【No declare:517ms】【Use declare:380ms】【Map:1278ms】
----------------------------------------------------------------------
第91次:【Foreach:821ms】【No declare:511ms】【Use declare:345ms】【Map:1258ms】
----------------------------------------------------------------------
第92次:【Foreach:834ms】【No declare:506ms】【Use declare:347ms】【Map:1248ms】
----------------------------------------------------------------------
第93次:【Foreach:866ms】【No declare:488ms】【Use declare:353ms】【Map:1256ms】
----------------------------------------------------------------------
第94次:【Foreach:832ms】【No declare:503ms】【Use declare:352ms】【Map:1251ms】
----------------------------------------------------------------------
第95次:【Foreach:833ms】【No declare:480ms】【Use declare:333ms】【Map:1192ms】
----------------------------------------------------------------------
第96次:【Foreach:809ms】【No declare:494ms】【Use declare:341ms】【Map:1227ms】
----------------------------------------------------------------------
第97次:【Foreach:829ms】【No declare:475ms】【Use declare:349ms】【Map:1223ms】
----------------------------------------------------------------------
第98次:【Foreach:843ms】【No declare:481ms】【Use declare:329ms】【Map:1215ms】
----------------------------------------------------------------------
第99次:【Foreach:842ms】【No declare:483ms】【Use declare:356ms】【Map:1201ms】
----------------------------------------------------------------------
第100次:【Foreach:818ms】【No declare:495ms】【Use declare:341ms】【Map:1240ms】
----------------------------------------------------------------------
 
Mean time rank:【Use declare:358.35ms】【No declare:490.68ms】【Foreach:851.43ms】【Map:1230.29ms】

五、总结

  1. for 循环是最简单的,因为它没有任何额外的函数调用栈和上下文;
  2. forEach 其次,因为它其实比我们想象得要复杂一些,它的函数签名实际上是array.forEach(function(currentValue, index, arr), thisValue) 它不是普通的 for 循环的语法糖,还有诸多参数和上下文需要在执行的时候考虑进来,这里可能拖慢性能;
  3. map 最慢,因为它的返回值是一个等长的全新的数组,数组创建和赋值产生的性能开销很大。
  4. 需要将数组按照某种规则映射为另一个数组,就应该用 map。
  5. 如果需要进行简单的遍历,用 forEach 或者 for of。
  6. 需要对迭代器进行遍历,用 for of.
  7. 如果需要过滤出符合条件的项,用 filter.
  8. 如果需要先按照规则映射为新数组,再根据条件过滤,那就用一个 map 加一个 filter。不要担心这样会慢,一般数据量浏览器根本不 care。
  9. 如果真的需要考虑性能,或者有 break 的需求,就用 for 吧。
  10. 优化版使用临时变量,将长度缓存起来,避免重复获取数组长度,当数组较大时优化效果才会比较明显。整体性能排行 是for循环(写声明)> for循环(不写声明) > forEach > map

至此,前端的各种循环方式的性能评测及场景使用建议就基本完成啦,希望能帮到小伙伴们~

声明:Xuhao's Blog|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - 探究前端中各种循环的执行性能


Carpe Diem and Do what I like