js 性能优化之算法和流程控制


Posted in Javascript onFebruary 15, 2017

循环处理是最常见的编程模式之一,也是提升性能必须关注的要点之一。

常见的优化方案有:

①JavaScript的四种循环(for、do-while、while、for-in)中,for-in循环比其他几种明显要慢。由于每次迭代操作会同时搜索实例或原型属性,for-in循环的每次迭代都会产生更多的开销,所以比其他类型要慢。因此遍历一个属性数量有限的已知属性列表,可以这样优化:

var props = ['prop1', 'prop2'],i = 0;
whlie(i < props.length){
 precess(object[props[i++]]);
}

该代码只关注给定的属性,减少了循环的开销。

而对于,for、while、do-while。我在chrome下测试了一下,先创建一个大小为1000000的数组,每项乘100再叠加。

测试用例:

window.onload = function(){
var items = Array(1000000).join(',').split(',').map(function(item, index) {
 return index;
});
 console.log(forCircle())
 console.log(whileCircle())
 console.log(doCircle())
function forCircle(){
console.profile();
var currTime = new Date();
 var tal = 0;
 for(var i = 0;i < items.length; i++){
  tal = tal + process(items[i]);
 }
 console.profileEnd();
 console.log('forCircle用时:' + (new Date() - currTime) + 'ms');
 return tal;
}
function whileCircle(){
console.profile();
var currTime = new Date();
 var tal = 0;
 var j = 0;
 while (j < items.length){
  tal = tal + process(items[j++]);
 }
 console.profileEnd();
 console.log('whileCircle用时:' + (new Date() - currTime) + 'ms');
 return tal;
}
function doCircle(){
console.profile();
var currTime = new Date();
 var tal = 0;
 var k = 0;
 do{
  tal = tal + process(items[k++]);
 }while (k < items.length)
  console.profileEnd();
 console.log('doCircle用时:' + (new Date() - currTime) + 'ms');
 return tal;
}
function process(item){
 return item*100;
}
}

取某次测试结果:

js 性能优化之算法和流程控制

js 性能优化之算法和流程控制

js 性能优化之算法和流程控制

平均来说,for循环耗时8ms,while耗时4ms,doWhile耗时也是4ms。for是最慢的。

②减少迭代的工作量。把数组长度保存在局部变量中再遍历、颠倒数组的遍历顺序。

最常见的一个循环:

for(var i = 0;i < items.length; i++){
 process(items[i]);
}
//
var j = 0;
while (j < items.length){
 process(items[j++]);
}
//
var k = 0;
do{
 process(items[k++]);
}while (k < items.length)

在这个循环中,每次运行都会产生如下操作:

①查找一次属性(items.length)

②执行数值比较一次(i < items.length) 

③查看控制条件是否为true(i < items.length ==true) 

④一次自增操作(i++)

⑤一次数组查找(items[i])

⑥一次函数调用(process(items[i]))

若把数组长度存到一个局部变量,那么就不需要每次都查找一次items.length,也就提高了性能。

改为这样:

for(var i = 0, len = items.length;i < len; i++){
 process(items[i]);
}
//
var j = 0,
count = items.length;
while (j < count){
 process(items[j++]);
}
//
var k = 0,
num = items.length;
do{
 process(items[k++]);
}while (k < num)

这样在大多数浏览器中能节省大概25%的运行时间(IE中甚至可以节省50%)。总的来说,循环次数大的情况下,运行时间确实有提升。取某次结果如下:

没有局部存量存储数组长度时:

js 性能优化之算法和流程控制

有局部变量存储数组长度时:

js 性能优化之算法和流程控制

③减少迭代次数,“Duffs Device”即“达夫设备“循环体展开技术。适合于迭代次数较大的情况下。

摘抄一下书中达夫设备的基本理念:每次循环中最多可 8 次调用 process()函数。循环迭代次数为元素总数除以8。 因为总数不一定是 8的整数倍, 所以 startAt 变量存放余数, 指出第一次循环中应当执行多少次 process()。比方说现在有 12 个元素,那么第一次循环将调用 process()4次,第二次循环调用 process()8 次,用 2 次循环代替了 12次循环。

基本模式:

var iterations = Math.floor(items.length/8), 
 startAt = items.length%8, 
 i = 0; 
do{ 
 switch(startAt){ 
  case 0 : process(items[i++]); 
  case 7 : process(items[i++]); 
  case 6 : process(items[i++]); 
  case 5 : process(items[i++]); 
  case 4 : process(items[i++]); 
  case 3 : process(items[i++]); 
  case 2 : process(items[i++]); 
  case 1 : process(items[i++]); 
 } 
 startAt = 0; 
 }while(--iterations);

④基于函数的迭代比基于循环的迭代消耗性能更多。例:for循环迭代与forEach函数迭代。 

⑤优化if-else,通常来说,switch比if-else快,但是在判断条件较多时,使用查找表比if-else和switch都快。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木! 

Javascript 相关文章推荐
javascript JSON操作入门实例
Apr 16 Javascript
js实现鼠标感应向下滑动隐藏菜单的方法
Feb 20 Javascript
使用jQuery Ajax 请求webservice来实现更简练的Ajax
Aug 04 Javascript
jsp 自动编译机制详细介绍
Dec 01 Javascript
js实现自定义进度条效果
Mar 15 Javascript
详解vue父子组件间传值(props)
Jun 29 Javascript
基于webpack4搭建的react项目框架的方法
Jun 30 Javascript
Vue 组件封装 并使用 NPM 发布的教程
Sep 30 Javascript
基于elementUI使用v-model实现经纬度输入的vue组件
May 12 Javascript
vue-cli3 配置开发与测试环境详解
May 17 Javascript
js回溯法计算最佳旅行线路代码实例
Sep 11 Javascript
10分钟学会js处理json的常用方法
Dec 06 Javascript
微信小程序 常用工具类详解及实例
Feb 15 #Javascript
微信小程序 基础知识css样式media标签
Feb 15 #Javascript
js 性能优化之快速响应的用户界面
Feb 15 #Javascript
微信小程序  http请求封装详解及实例代码
Feb 15 #Javascript
DOM事件探秘篇
Feb 15 #Javascript
详解Angularjs 如何自定义Img的ng-load 事件
Feb 15 #Javascript
js实现滑动到页面底部自动加载更多功能
Feb 15 #Javascript
You might like
用PHP创建PDF中文文档
2006/10/09 PHP
php checkbox 取值详细说明
2010/08/19 PHP
基于PHP编程注意事项的小结
2013/04/27 PHP
php防止站外远程提交表单的方法
2014/10/20 PHP
php强制用户转向www域名的方法
2015/06/19 PHP
php实现网页端验证码功能
2017/07/11 PHP
php递归函数怎么用才有效
2018/02/24 PHP
Yii框架多语言站点配置方法分析【中文/英文切换站点】
2020/04/07 PHP
jQuery的DOM操作之删除节点示例
2014/01/03 Javascript
JavaScript中的对象序列化介绍
2014/12/30 Javascript
JavaScript实现将文本框的值插入指定位置的方法
2015/08/13 Javascript
jquery ajax后台返回list,前台用jquery遍历list的实现
2016/10/30 Javascript
微信小程序 特效菜单抽屉效果实例代码
2017/01/11 Javascript
Nodejs中Express 常用中间件 body-parser 实现解析
2017/05/22 NodeJs
seaJs使用心得之exports与module.exports的区别实例分析
2017/10/13 Javascript
webpack4.0 入门实践教程
2018/10/08 Javascript
React学习之受控组件与数据共享实例分析
2020/01/06 Javascript
微信小程序仿抖音视频之整屏上下切换功能的实现代码
2020/05/24 Javascript
vue-cli3自动消除console.log()的调试信息方式
2020/10/21 Javascript
Python实现上下班抢个顺风单脚本
2018/02/07 Python
基于python中theano库的线性回归
2018/08/31 Python
python实现n个数中选出m个数的方法
2018/11/13 Python
python pygame实现2048游戏
2018/11/20 Python
使用python批量化音乐文件格式转换的实例
2019/01/09 Python
Pandas之groupby( )用法笔记小结
2019/07/23 Python
pytorch 状态字典:state_dict使用详解
2020/01/17 Python
在pytorch 中计算精度、回归率、F1 score等指标的实例
2020/01/18 Python
如何基于Python Matplotlib实现网格动画
2020/07/20 Python
The Hut美国/加拿大:英国领先的豪华在线百货商店
2019/03/26 全球购物
《长相思》听课反思
2014/04/10 职场文书
员工年终自我评价
2014/09/14 职场文书
党支部遵守党的政治纪律情况对照检查材料
2014/09/26 职场文书
2015年大学生工作总结
2015/04/21 职场文书
消防验收申请报告
2015/05/15 职场文书
运动会入场词
2015/07/18 职场文书
Python机器学习应用之基于线性判别模型的分类篇详解
2022/01/18 Python