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中的location用法简单介绍
Mar 07 Javascript
使用简洁的jQuery方法实现隔行换色功能
Jan 02 Javascript
一个不错的仿携程自定义数据下拉选择select
Sep 01 Javascript
谈谈jQuery Ajax用法详解
Nov 27 Javascript
gameboy网页闯关游戏(riddle webgame)--仿微信聊天的前端页面设计和难点
Feb 21 Javascript
Bootstrap插件全集
Jul 18 Javascript
Ajax使用原生态JS验证用户名是否存在
May 26 Javascript
js实现百度登录框鼠标拖拽效果
Mar 07 Javascript
判断div滑动到底部的scroll实例代码
Nov 15 Javascript
浅谈React中的元素、组件、实例和节点
Feb 27 Javascript
js 实现碰撞检测的示例
Oct 28 Javascript
jquery实现淡入淡出轮播图效果
Dec 13 jQuery
微信小程序 常用工具类详解及实例
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+MySQL 手工注入语句大全 推荐
2009/10/30 PHP
Flash对联广告的关闭按钮讨论
2007/01/30 Javascript
Javascript 二维数组
2009/11/26 Javascript
jquery 的 $(&quot;#id&quot;).html() 无内容的解决方法
2010/06/07 Javascript
jQuery EasyUI API 中文文档 - Tabs标签页/选项卡
2011/10/01 Javascript
AngularJS入门教程之学习环境搭建
2014/12/06 Javascript
轻松创建nodejs服务器(5):事件处理程序
2014/12/18 NodeJs
JS实现网页上随滚动条滚动的层效果代码
2015/11/04 Javascript
深入浅析JavaScript中的arguments对象(强力推荐)
2016/06/03 Javascript
JavaScript 对象字面量讲解
2016/06/06 Javascript
JS实现一次性弹窗的方法【刷新后不弹出】
2016/12/26 Javascript
jquery实现限制textarea输入字数的方法
2017/09/06 jQuery
vue路由跳转时判断用户是否登录功能的实现
2017/10/26 Javascript
vue实现前进刷新后退不刷新效果
2018/01/26 Javascript
vue+iview/elementUi实现城市多选
2019/03/28 Javascript
详解JavaScript的内存空间、赋值和深浅拷贝
2019/04/17 Javascript
layui-select动态选中值的例子
2019/09/23 Javascript
vue 使用 canvas 实现手写电子签名
2020/03/06 Javascript
[01:15:18]2014 DOTA2国际邀请赛中国区预选赛 LGD VS Speed Gaming.cn
2014/05/22 DOTA
[02:49]2018DOTA2亚洲邀请赛主赛事决赛日战况回顾 Mineski鏖战5局夺得辉耀
2018/04/10 DOTA
Django框架实现分页显示内容的方法详解
2019/05/10 Python
一篇文章了解Python中常见的序列化操作
2019/06/20 Python
python类的实例化问题解决
2019/08/31 Python
Python numpy数组转置与轴变换
2019/11/15 Python
Python脚本导出为exe程序的方法
2020/03/25 Python
Django实现列表页商品数据返回教程
2020/04/03 Python
Python实现http接口自动化测试的示例代码
2020/10/09 Python
CSS3中的@keyframes关键帧动画的选择器绑定
2016/06/13 HTML / CSS
html5 CSS过度-webkit-transition使用介绍
2013/07/02 HTML / CSS
刘胡兰的英雄事迹材料
2014/02/11 职场文书
文明班级申报材料
2014/12/24 职场文书
高考诚信考试承诺书
2015/04/29 职场文书
在职证明书模板
2015/06/15 职场文书
珍爱生命主题班会
2015/08/13 职场文书
MySQL 不等于的三种使用及区别
2021/06/03 MySQL
Android移动应用开发指南之六种布局详解
2022/09/23 Java/Android