JavaScript,for循环效率测试,不同遍历循环测试,数组添加效率测试,大数组拼接测试,for循环遍历修改 和 string replace效率
for循环估计是大家平时用到的最多的循环遍历了,一般情况下大家都会使用编程软件写一个for敲一下Tab,自动生成for循环结构
for (let index = 0; index < array.length; index++) {
const element = array[index];
}
应为for循环用的比较多,那有没有什么方法能提高一下for循环的效率,观察主体结构,index
没什么好说的,循环的索引,中间的<
是循环跳出的条件,逻辑运算符,也不能动,只能向array.length
下手了,我们知道每次循环的时候都需要用index
和array.length
比较,而获取array.length
时,还需要计算一下数组元素的长度,这就导致了每次循环都要计算一次,所以我们可以提前把这个长度计算出来,存入变量,用的时候直接来取。
let arr = [];
//创建一个数组,提供测试
function arrCreat() {
for (let index = 0; index < 1000000; index++) {
arr.push(false);
}
}
arrCreat();
//不提前计算长度,遍历数组
function forNolength(arr) {
for (let index = 0; index < arr.length; index++) {
if(arr[index].boolean === false) {
arr[index].boolean = true;
}
}
}
console.time('NoNoNo1');
forNolength(arr);
console.timeEnd('NoNoNo1');
//提前计算长度,遍历数组
function forAndLength(arr) {
for (let index = 0, length = arr.length;index < length; index++) {
if(arr[index].boolean === false) {
arr[index].boolean = true;
}
}
}
console.time('forAndLength1');
forAndLength(arr);
console.timeEnd('forAndLength1');
查看遍历时间(NoNoNo表示没有提前计算长度,forAndLength表示没有提前计算长度)
第二次运行结果
第三次
可以看出提前计算长度的循环时间都比较短,减少计算,提高运算速度,虽然差别不大,但是蚊子肉也是肉,能快一点是一点,不过由于提前把
length
计算出来,会额外需要一块内存用来存放length,不过使用的是let
定义,循环结束,这块内存就会释放掉。想要内存使用少,遍历速度又快的话,只能研究一种更高明的算法了。
for系列遍历循环测试
- for
- forEach
- for in
- for of
- map
- filter
function nativeFor(array) {
for (let index = 0, length = array.length; index < length; index++) {
if(arr[index].boolean === false) {
arr[index].boolean = true;
}
}
}
console.time('nativeFor');
nativeFor(arr);
console.timeEnd('nativeFor');
function forEach(array) {
array.forEach((element) => {
if (element.boolean === false) {
element.boolean = true;
}
});
}
console.time('forEach');
forEach(arr);
console.timeEnd('forEach');
function forIn(array) {
for (const key in array) {
if (array[key].boolean === false) {
array[key].boolean = true;
}
}
}
console.time('forIn');
forIn(arr);
console.timeEnd('forIn');
function forOf(array) {
for (const iterator of array) {
if (iterator.boolean === false) {
iterator.boolean = true;
}
}
}
console.time('forOf');
forOf(arr);
console.timeEnd('forOf');
function forMap(array) {
array.map((element) => {
if (element.boolean === false) {
element.boolean = true;
}
});
}
console.time('forMap');
forMap(arr);
console.timeEnd('forMap');
function filter(array) {
array.filter((item) => {
return item === false;
});
}
console.time('filter');
filter(arr);
console.timeEnd('filter');
运行结果
上面虽然
for in
的时间比较长,是因为for in
设计之初是用来遍历对象的,for
循环只能遍历数组,数组也是对象,数组中的属性和方法,for in
也可以遍历出来,其中为了不把原型上的属性和方法遍历出来,还需要增加obj.hasOwnProperty(prop)
用来判断是否为原型上的属性或方法。forEach
ES5提供的遍历方法,写法简单,但是不能跳出,性情比较直爽,不循环出来,不罢休。for of
ES6提供的遍历方法,可以使用continue和break。filter
循环,通常用于过滤数组元素。map
会让原数组中的每个值通过匿名函数,产生一个对应的值,然后返回一个新的数组所以从执行效率来看,使用消耗最多,因为做的工作更多,开辟了新地址,再把原数据一个一个走一遍函数,之后再存进新地方。以上的执行效率会随着计算机的运行状态变化而变化,并不是唯一确定的,大家做个参考就可以了,个人推荐使用的遍历方法
for of
写法比较简单,而且也是ES6中新增的方法,建议大家使用。
数组添加效率比较
let baseArrStr = ['123', '456', '789'];
function concatArrFunc() {
let tempArr = [];
for (let index = 0; index < 10000; index++) {
tempArr = tempArr.concat(baseArrStr);
}
}
console.time('concatArrFunc');
concatArrFunc(arr);
console.timeEnd('concatArrFunc');
function pushArrFunc() {
let tempArr = [];
for (let index = 0; index < 10000; index++) {
for (let index1 = 0, length = baseArrStr.length; index1 < length; index1++) {
tempArr.push(baseArrStr[index1]);
}
}
}
console.time('pushArrFunc');
pushArrFunc(arr);
console.timeEnd('pushArrFunc');
function extendArrFunc() {
let tempArr = [];
for (let index = 0; index < 10000; index++) {
tempArr.push(...baseArrStr);
}
}
console.time('extendArrFunc');
extendArrFunc(arr);
console.timeEnd('extendArrFunc');
function applyArrFunc() {
let tempArr = [];
for (let index = 0; index < 10000; index++) {
Array.prototype.push.apply(tempArr, baseArrStr);
}
}
console.time('applyArrFunc');
applyArrFunc(arr);
console.timeEnd('applyArrFunc');
请注意,大家看一下
extendArrFunction
的执行结果,...
是ES6的扩展运算符,ES6是真的香,执行效率快,最最最最主要的是太方便了,而且这几个函数里面,是不是感觉extendArrFunc
这个最有牌面,能小装一下。
- 两个大数组拼接,看看执行效率会有什么变化
let arr1 = [];
let arr2 = [];
function arrCreat() {
for (let index = 0; index < 100000; index++) {
arr1.push('123');
arr2.push('123');
}
}
arrCreat();
function concatArrFunc(arr1, arr2) {
arr1 = arr1.concat(arr2);
}
console.time('concatArrFunc');
concatArrFunc(arr1, arr2);
console.timeEnd('concatArrFunc');
function pushArrFunc(arr1, arr2) {
for (let index = 0, length = arr2.length; index < length; index++) {
arr1.push(arr2[index]);
}
}
console.time('pushArrFunc');
pushArrFunc(arr1, arr2);
console.timeEnd('pushArrFunc');
function extendArrFunc(arr1, arr2) {
arr1.push(...arr2);
}
console.time('extendArrFunc');
extendArrFunc(arr1, arr2);
console.timeEnd('extendArrFunc');
function applyArrFunc(arr1, arr2) {
Array.prototype.push.apply(arr1, arr2);
}
console.time('applyArrFunc');
applyArrFunc(arr1, arr2);
console.timeEnd('applyArrFunc');
运行结果如下
这里可以直观的看出来
concat
在拼接较大数组时候的效率,还是很可观的大家编写程序的时候,可根据不同情况下的使用不同的方法,虽然几种方法差别不大,但是积少成多,少用点时间,页面响应就能快一点,当然了,部分情况还需要考虑到内存的使用情况,执行效率增加后,相应的可能会占用更多的内存,之间的利弊怎么衡量,看各位小伙伴的项目需要了。
该篇文章借鉴了沈老师的关于for循环效率测试的内容,如果有侵权,请联系我删除。