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 相关文章推荐
jQuery链式操作如何实现以及为什么要用链式操作
Jan 17 Javascript
原生js实现给指定元素的后面追加内容
Apr 10 Javascript
jQuery中hide()方法用法实例
Dec 24 Javascript
js图片轮播特效代码分享
Sep 07 Javascript
jQuery实现无限往下滚动效果代码
Apr 16 Javascript
jQuery新窗口打开外链接
Jul 21 Javascript
jquery datatable服务端分页
Aug 31 Javascript
Vue.js实现拖放效果的实例
Sep 30 Javascript
bootstrap table服务端实现分页效果
Aug 10 Javascript
详解Vue CLI3配置之filenameHashing使用和源码设计使用和源码设计
Aug 31 Javascript
vue使用代理解决请求跨域问题详解
Jul 24 Javascript
关于antd tree 和父子组件之间的传值问题(react 总结)
Jun 02 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
中国的第一台收音机
2021/03/01 无线电
Thinkphp 框架扩展之驱动扩展实例分析
2020/04/27 PHP
dojo学习第一天 Tab选项卡 实现
2011/08/28 Javascript
JavaScript DOM操作表格及样式
2015/04/13 Javascript
Bootstrap媒体对象的实现
2016/05/01 Javascript
jquery的ajax提交form表单的两种方法小结(推荐)
2016/05/25 Javascript
Bootstrap表单使用方法详解
2017/02/17 Javascript
微信小程序微信支付接入开发实例详解
2017/04/12 Javascript
页面缩放兼容性处理方法(zoom,Firefox火狐浏览器)
2017/08/29 Javascript
vue父组件点击触发子组件事件的实例讲解
2018/02/08 Javascript
详解自定义ajax支持跨域组件封装
2018/02/08 Javascript
jQuery实现轮播图及其原理详解
2020/04/12 jQuery
Vue中 key keep-alive的实现原理
2018/09/18 Javascript
JavaScript数据结构与算法之检索算法实例分析【顺序查找、最大最小值、自组织查询】
2019/02/22 Javascript
JS实现查找数组中对象的属性值是否存在示例
2019/05/24 Javascript
JS中实现一个下载进度条及播放进度条的代码
2019/06/10 Javascript
Vue+Koa2+mongoose写一个像素绘板的实现方法
2019/09/10 Javascript
JS面试题中深拷贝的实现讲解
2020/05/07 Javascript
在vue中使用Echarts利用watch做动态数据渲染操作
2020/07/20 Javascript
Postman参数化实现过程及原理解析
2020/08/13 Javascript
vue中如何添加百度统计代码
2020/12/19 Vue.js
Python struct模块解析
2014/06/12 Python
Python的Flask框架中web表单的教程
2015/04/20 Python
详解Python的单元测试
2015/04/28 Python
python中ImageTk.PhotoImage()不显示图片却不报错问题解决
2018/12/06 Python
pytorch+lstm实现的pos示例
2020/01/14 Python
IE滤镜与CSS3效果(详细整理分享)
2013/01/25 HTML / CSS
HTML5 Canvas中使用用路径描画圆弧
2015/01/01 HTML / CSS
HTML5中meta属性的使用方法
2016/02/29 HTML / CSS
英国护肤品购物网站:Beauty Expert
2016/08/19 全球购物
大四毕业生学习总结的自我评价
2013/10/31 职场文书
标准毕业生自荐信
2014/06/24 职场文书
学生会干部自我鉴定2014
2014/09/18 职场文书
开学典礼致辞
2015/07/29 职场文书
自愿离婚协议书范本2016
2016/03/18 职场文书
JavaScript文档对象模型DOM
2021/11/20 Javascript