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 必填项判断表单是否为空的方法
Sep 14 Javascript
javascript中打印当前的时间实现思路及代码
Dec 18 Javascript
js实现Form栏显示全格式时间时钟效果代码
Aug 19 Javascript
jQuery实现带有上下控制按钮的简单多行滚屏效果代码
Sep 04 Javascript
Jquery promise实现一张一张加载图片
Nov 13 Javascript
Javascript中内建函数reduce的应用详解
Oct 20 Javascript
关于bootstrap日期转化,bootstrap-editable的简单使用,bootstrap-fileinput的使用详解
May 12 Javascript
jQuery实现的弹幕效果完整实例
Sep 06 jQuery
vue 优化CDN加速的方法示例
Sep 19 Javascript
微信小程序自定义轮播图
Nov 04 Javascript
VUE组件中的 Drawer 抽屉实现代码
Aug 06 Javascript
Ajax实现三级联动效果
Oct 05 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获取类中常量,属性,及方法列表的方法
2009/04/09 PHP
PHP OPCode缓存 APC详细介绍
2010/10/12 PHP
PHP Error与Logging函数的深入理解
2013/06/03 PHP
PHP使用内置dir类实现目录遍历删除
2015/03/31 PHP
php数组冒泡排序算法实例
2016/05/06 PHP
JS实现点击图片在当前页面放大并可关闭的漂亮效果
2013/10/18 Javascript
让input框实现类似百度的搜索提示(基于jquery事件监听)
2014/01/31 Javascript
from表单多个按钮提交用onclick跳转不同action
2014/04/24 Javascript
JavaSript中变量的作用域闭包的深入理解
2014/05/12 Javascript
Js使用WScript.Shell对象执行.bat文件和cmd命令
2014/12/18 Javascript
js运动动画的八个知识点
2015/03/12 Javascript
jQuery实现径向动画菜单效果
2015/07/17 Javascript
微信小程序 图片绝对定位(背景图片)
2017/04/05 Javascript
Vue.js中的图片引用路径的方式
2017/07/28 Javascript
node.js 用socket实现聊天的示例代码
2017/10/17 Javascript
vue axios封装及API统一管理的方法
2019/04/18 Javascript
微信小程序分包加载代码实现方法详解
2019/09/23 Javascript
js实现超级玛丽小游戏
2020/03/18 Javascript
js实现3D粒子酷炫动态旋转特效
2020/09/13 Javascript
[01:19]DOTA2城市挑战赛报名开始 开启你的城市传奇
2018/03/23 DOTA
进一步探究Python中的正则表达式
2015/04/28 Python
Python实现PS图像调整之对比度调整功能示例
2018/01/26 Python
python实现简单的文字识别
2018/11/27 Python
利用python如何在前程无忧高效投递简历
2019/05/07 Python
Python实现ATM系统
2020/02/17 Python
pytorch 实现在一个优化器中设置多个网络参数的例子
2020/02/20 Python
python实现字符串和数字拼接
2020/03/02 Python
关于Python turtle库使用时坐标的确定方法
2020/03/19 Python
美国鲍勃商店:Bob’s Stores
2018/07/22 全球购物
师范生个人推荐信
2013/11/29 职场文书
车间工艺员岗位职责
2013/12/09 职场文书
座谈会主持词
2014/03/20 职场文书
大二学习计划书范文
2014/04/27 职场文书
副总经理党的群众路线教育实践活动个人对照检查材料思想汇报
2014/10/06 职场文书
2016应届毕业生实习评语
2015/12/01 职场文书
Apache Hudi的多版本清理服务彻底讲解
2022/03/31 Servers