JavaScript for 、for...of 、for...in 等 iteration 效率测试
程序员文章站
2022-03-26 12:12:15
由于不同浏览器,不同版本性能不一,且控制台本质是是套用了一大堆 "eval" ,沙盒化程度高,所以需使用 "node" 环境测试来提高准确性 比第二种方法更简洁 倒叙简洁版 两个分号之间的表达式为 true 会一直执行直到 判断为 false (i = 0) 正序简洁版 当 i 大于等于数组长度或a ......
- 由于不同浏览器,不同版本性能不一,且控制台本质是是套用了一大堆,沙盒化程度高,所以需使用环境测试来提高准确性
// 准备待测数组 const num = 1e7; let arr = new array(num).fill(1); // for 测试 let arr1 =[]; console.time('for'); for (let i = 0; i < arr.length; i++) { arr1.push(arr[i]) } console.timeend('for'); // chrome/75.0.3770.100 safari/537.36 环境 //vm1324:10 for: 576.733154296875ms // node v10.11.0 环境 // for: 412.087ms
for 几种写法
- 常规写法
let arr1 = [] console.time('one') for (let i = 0; i < arr.length; i++ ){ arr1.push(arr[i]) } console.timeend('one')
数组长度是会动态变化,每次循环会重新计算length长度,可能会出现死循环
- cache arr.length
for (let i = 0, len = arr.length; i < len; i++ ){ arr1.push(arr[i]) }
缓存length 值,无需重新计算length
- 倒序
for (let i = arr.length-1; i >= 0; i--){ arr1.push(arr[i]) }
比第二种方法更简洁
- 倒叙简洁版
for (let i = arr.length-1; i--;){ arr1.push(arr[i]) }
两个分号之间的表达式为 true 会一直执行直到 判断为 false (i = 0)
- 正序简洁版
for (let i = 0, len;len = arr[i++]; ){ arr1.push(arr[i]) }
当 i 大于等于数组长度或arr[i++]值为false时 将停指循环,同时由于arr.length动态变化时可能会造成死循环
for...of
for (let value of arr){ arr1.push(value) }
es6推出的迭代器,最简洁,可以是用 break,continue和return 终止循环
for...in
for (let key in arr){ arr1.push(arr[key]) }
for...in 一般用于遍历对象,他会将本身属性和原型链上的属性(除系统内置属性)全部遍历出来即便是不可枚举属性(enumerable:false), 可以通过 items.hasownproperty
来遍历本身属性,由于查询到自己的原型链上,所以性能方面比较差
foreach
arr.foreach(function(value){ arr1.push(value) })
数组的迭代方法,没有返回值
map
arr.map(function(value){ return arr1.push(value) })
浅拷贝原数组,并且返回一个新数组
性能测试
测试次数 | 常规for | cache for | 倒序 for | 倒叙简版 for | 正序简版 for | for..of | for..in | foreach | map |
---|---|---|---|---|---|---|---|---|---|
1 | 542.121ms | 573.618ms | 764.181ms | 755.961ms | 571.464ms | 945.199ms | 4077.020ms | 625.859ms | 3573.946ms |
2 | 430.008ms | 541.933ms | 524.474ms | 668.276ms | 553.475ms | 897.442ms | 4402.246ms | 605.271ms | 2732.859ms |
3 | 409.531ms | 661.765ms | 534.167ms | 655.481ms | 600.939ms | 1141.093ms | 3806.704ms | 584.712ms | 2779.192ms |
4 | 412.972ms | 643.868ms | 536.026ms | 674.081ms | 725.149ms | 930.655ms | 3201.387ms | 599.780ms | 3152.499ms |
5 | 417.034ms | 624.323ms | 520.674ms | 799.568ms | 574.713ms | 943.449ms | 3261.512ms | 587.182ms | 2954.195ms |
6 | 525.771ms | 955.737ms | 526.208ms | 771.443ms | 531.962ms | 954.199ms | 4351.009ms | 608.264ms | 2888.752ms |
7 | 498.039ms | 602.703ms | 555.588ms | 531.464ms | 541.599ms | 916.678ms | 3264.334ms | 596.168ms | 2834.663ms |
8 | 431.694ms | 523.381ms | 544.974ms | 527.472ms | 517.833ms | 1049.283ms | 3744.972ms | 600.286ms | 3467.499ms |
9 | 417.521ms | 518.093ms | 547.404ms | 611.024ms | 594.503ms | 767.059ms | 4979.348ms | 601.420ms | 3638.023ms |
10 | 424.806ms | 557.961ms | 535.541ms | 837.561ms | 541.882ms | 772.686ms | 3284.424ms | 602.443ms | 3599.642ms |
11 | 409.402ms | 521.131ms | 534.265ms | 517.709ms | 551.397ms | 752.101ms | 3228.123ms | 629.625ms | 3535.545ms |
12 | 425.362ms | 532.882ms | 406.637ms | 522.287ms | 570.259ms | 914.135ms | 3449.256ms | 800.857ms | 3429.123ms |
平均值 | 439.2738ms | 578.3565ms | 553.1468ms | 651.7057ms | 507.8718ms | 909.0785ms | 3,686.9 6ms | 605.6298ms | 3,221.5056ms |
堆值差 | 357245536byte | 357245808byte | 357245624byte | 357245872byte | 357246824byte | 199268080byte | 757187208byte | 357244456byte | 43724764byte |
测试总结
-
运行效率:
常规for
>正序简版 for
>倒序 for
>cache for
>倒叙简版 for
>foreach
>for..of
>map
>for..in
- 几种普通 for 循环占用内存相差不大, 而
for..of
占用运行内存最小 -
for..in
性能最差,内存占用高,速度很慢