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 相关文章推荐
JS 控制小数位数的实现代码
Aug 02 Javascript
JS解析json数据并将json字符串转化为数组的实现方法
Dec 25 Javascript
纯JavaScript实现HTML5 Canvas六种特效滤镜示例
Jun 28 Javascript
JQuery性能优化的几点建议
May 14 Javascript
jQuery插件Tooltipster实现漂亮的工具提示
Apr 12 Javascript
jQuery实现的指纹扫描效果实例(附演示与demo源码下载)
Jan 26 Javascript
微信小程序 自定义消息提示框
Aug 06 Javascript
微信小程序仿RadioGroup改变样式的处理方案
Jul 13 Javascript
BootStrap模态框闪退问题实例代码详解
Dec 10 Javascript
vuex 解决报错this.$store.commit is not a function的方法
Dec 17 Javascript
JS代码检查工具ESLint介绍与使用方法
Feb 04 Javascript
Vue组件更新数据v-model不生效的解决
Apr 02 Vue.js
微信小程序 常用工具类详解及实例
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游戏编程25个脚本代码
2011/02/08 PHP
php对csv文件的读取,写入,输出下载操作详解
2013/08/10 PHP
BOOM vs RR BO5 第三场 2.14
2021/03/10 DOTA
js获取当前select 元素值的代码
2010/04/19 Javascript
js封装的textarea操作方法集合(兼容很好)
2010/11/16 Javascript
IE 当eval遇上function的处理
2011/08/09 Javascript
整理8个很棒的 jQuery 倒计时插件和教程
2011/12/12 Javascript
jquery 实现表单验证功能代码(简洁)
2012/07/03 Javascript
JS+CSS实现一个气泡提示框
2013/08/18 Javascript
Iframe实现跨浏览器自适应高度解决方法
2014/09/02 Javascript
基于jQuery实现文本框缩放以及上下移动功能
2014/11/24 Javascript
jQuery实现Div拖动+键盘控制综合效果的方法
2015/03/10 Javascript
浅谈javascript的Touch事件
2015/09/27 Javascript
JQuery实现DIV其他动画效果的简单实例
2016/09/18 Javascript
通过BootStrap实现轮播图的实际应用
2016/09/26 Javascript
jQuery扩展+xml实现表单验证功能的方法
2016/12/25 Javascript
jQuery 禁止表单用户名、密码自动填充功能
2017/10/30 jQuery
VueJs组件之父子通讯的方式
2018/05/06 Javascript
Koa2微信公众号开发之本地开发调试环境搭建
2018/05/16 Javascript
JS 实现分页打印功能
2018/05/16 Javascript
animate.css在vue项目中的使用教程
2018/08/05 Javascript
vue弹出框组件封装实例代码
2019/10/31 Javascript
稍微学一下Vue的数据响应式(Vue2及Vue3区别)
2019/11/21 Javascript
[36:13]Mineski vs iG 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
用Python写的图片蜘蛛人代码
2012/08/27 Python
Python微信库:itchat的用法详解
2017/08/14 Python
Python 图像处理: 生成二维高斯分布蒙版的实例
2019/07/04 Python
基于CSS3实现的几个小loading效果
2018/09/27 HTML / CSS
使用html5 canvas创建太空游戏的示例
2014/05/08 HTML / CSS
Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型
2013/10/30 面试题
三八妇女节演讲稿
2014/05/27 职场文书
群众路线四风问题整改措施
2014/09/27 职场文书
2014年宣传部工作总结
2014/11/12 职场文书
2014年统计工作总结
2014/11/21 职场文书
爱心捐款感谢信
2015/01/20 职场文书
呼兰河传读书笔记
2015/06/30 职场文书