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 相关文章推荐
IE8下关于querySelectorAll()的问题
May 13 Javascript
js 限制input只能输入数字、字母和汉字等等
Dec 18 Javascript
JS实现仿京东淘宝竖排二级导航
Dec 08 Javascript
jQuery中$.click()无效问题分析
Jan 29 Javascript
实例讲解jQuery EasyUI tree中state属性慎用
Apr 01 Javascript
jquery select2的使用心得(推荐)
Dec 04 Javascript
利用JS判断客户端类型你应该知道的四种方法
Dec 22 Javascript
JavaScript事件对象event用法分析
Jul 27 Javascript
浅谈Node 异步IO和事件循环
May 05 Javascript
Layui事件监听的实现(表单和数据表格)
Oct 17 Javascript
JavaScript多种滤镜算法实现代码实例
Dec 10 Javascript
关于Vue中$refs的探索浅析
Nov 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
DC宇宙的第一个英雄,堪称动漫史鼻祖,如今成为美国文化的象征
2020/04/09 欧美动漫
php 静态化实现代码
2009/03/20 PHP
PHP实现模仿socket请求返回页面的方法
2014/11/04 PHP
多浏览器支持的右下角浮动窗口
2010/04/01 Javascript
javaScript checkbox 全选/反选及批量删除
2010/04/28 Javascript
JavaScript 高级篇之DOM文档,简单封装及调用、动态添加、删除样式(六)
2012/04/07 Javascript
Google Dart编程语法和基本类型学习教程
2013/11/27 Javascript
jQuery事件绑定和委托实例
2014/11/25 Javascript
jquery通过扩展select控件实现支持enter或focus选择的方法
2015/11/19 Javascript
js实现图片无缝滚动
2015/12/23 Javascript
滚动条的监听与内容随着滚动条动态加载的实现
2017/02/08 Javascript
前端MVVM框架解析之双向绑定
2018/01/24 Javascript
解决vue-cli单页面手机应用input点击手机端虚拟键盘弹出盖住input问题
2018/08/25 Javascript
vue-router懒加载速度缓慢问题及解决方法
2018/11/25 Javascript
vue组件系列之TagsInput详解
2020/05/14 Javascript
jQuery实现鼠标滑动切换图片
2020/05/27 jQuery
python判断字符串是否包含子字符串的方法
2015/03/24 Python
python批量添加zabbix Screens的两个脚本分享
2017/01/16 Python
用Python抢火车票的简单小程序实现解析
2019/08/14 Python
python函数enumerate,operator和Counter使用技巧实例小结
2020/02/22 Python
Html5+CSS3+EL表达式问题小结
2020/12/19 HTML / CSS
简述网络文件系统NFS,并说明其作用
2016/10/19 面试题
程序员经常用到的UNIX命令
2015/04/13 面试题
如何通过 CSS 写出火焰效果
2021/03/24 HTML / CSS
专科毕业生自我鉴定
2013/12/01 职场文书
集体婚礼证婚词
2014/01/13 职场文书
人事部专员岗位职责
2014/03/04 职场文书
王老吉广告词
2014/03/20 职场文书
大学生标准自荐书
2014/06/15 职场文书
英语分层教学实施方案
2014/06/15 职场文书
学习张林森心得体会
2014/09/10 职场文书
三严三实民主生活会发言稿
2014/10/13 职场文书
2014年党员发展工作总结
2014/12/02 职场文书
倡议书的格式写法
2015/04/28 职场文书
看上去很美观后感
2015/06/10 职场文书
优质护理服务心得体会
2016/01/22 职场文书