热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

性能优化之算法和流程控制

循环处理是最常见的编程模式之一,也是提升性能必须关注的要点之一。常见的优化方案有:①JavaScript的四种循环(for、do-while、while、for-in)中,for-in循环比其他几
循环处理是最常见的编程模式之一,也是提升性能必须关注的要点之一。   常见的优化方案有:   ①Javascript的四种循环(for、do-while、while、for-in)中,for-in循环比其他几种明显要慢。由于每次迭代操作会同时搜索实例或原型属性,for-in循环的每次迭代都会产生更多的开销,所以比其他类型要慢。因此遍历一个属性数量有限的已知属性列表,可以这样优化:
var props = ['prop1', 'prop2'],i = 0;
whlie(i 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 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 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 console.profileEnd();
console.log('doCircle用时:' + (new Date() - currTime) + 'ms');
return tal;
}
function process(item){
return item*100;
}
}

 取某次测试结果:

   

 

平均来说,for循环耗时8ms,while耗时4ms,doWhile耗时也是4ms。for是最慢的。

  ②减少迭代的工作量。把数组长度保存在局部变量中再遍历、颠倒数组的遍历顺序。 最常见的一个循环:
for(var i = 0;i    process(items[i]);
}
//
var j = 0;
while (j process(items[j++]);
}
//
var k = 0;
do{
process(items[k++]);
}while (k

在这个循环中,每次运行都会产生如下操作:

①查找一次属性(items.length)

②执行数值比较一次(i

③查看控制条件是否为true(i

④一次自增操作(i++)

⑤一次数组查找(items[i])

⑥一次函数调用(process(items[i]))

若把数组长度存到一个局部变量,那么就不需要每次都查找一次items.length,也就提高了性能。

改为这样:

for(var i = 0, len = items.length;i    process(items[i]);
}
//
var j = 0,
count = items.length;
while (j process(items[j++]);
}
//
var k = 0,
num = items.length;
do{
process(items[k++]);
}while (k

  这样在大多数浏览器中能节省大概25%的运行时间(IE中甚至可以节省50%)。总的来说,循环次数大的情况下,运行时间确实有提升。取某次结果如下:

 没有局部存量存储数组长度时:

 

 有局部变量存储数组长度时:

③减少迭代次数,“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都快。   更多测试结论,可参考:http://www.cnblogs.com/hmking/archive/2011/10/10/2205321.html 更多学习可参考《高性能Javascript》    
推荐阅读
  • 深入理解:AJAX学习指南
    本文详细探讨了AJAX的基本概念、工作原理及其在现代Web开发中的应用,旨在为初学者提供全面的学习资料。 ... [详细]
  • 理解浏览器历史记录(2)hashchange、pushState
    阅读目录1.hashchange2.pushState本文也是一篇基础文章。继上文之后,本打算去研究pushState,偶然在一些信息中发现了锚点变 ... [详细]
  • Web开发实践:创建连连看小游戏
    本文详细介绍了如何在Web环境中开发一款连连看小游戏,适合初学者和技术爱好者参考。通过本文,您将了解游戏的基本结构、连线算法以及实现方法。 ... [详细]
  • 本文详细介绍了Socket在Linux内核中的实现机制,包括基本的Socket结构、协议操作集以及不同协议下的具体实现。通过这些内容,读者可以更好地理解Socket的工作原理。 ... [详细]
  • 个人博客:打开链接依赖倒置原则定义依赖倒置原则(DependenceInversionPrinciple,DIP)定义如下:Highlevelmo ... [详细]
  • Java高级工程师学习路径及面试准备指南
    本文基于一位朋友的PDF面试经验整理,涵盖了Java高级工程师所需掌握的核心知识点,包括数据结构与算法、计算机网络、数据库、操作系统等多个方面,并提供了详细的参考资料和学习建议。 ... [详细]
  • 本文探讨了如何通过优化 DOM 操作来提升 JavaScript 的性能,包括使用 `createElement` 函数、动画元素、理解重绘事件及处理鼠标滚动事件等关键主题。 ... [详细]
  • 使用jQuery与百度地图API实现地址转经纬度功能
    本文详细介绍了如何利用jQuery和百度地图API将地址转换为经纬度,包括申请API密钥、页面构建及核心代码实现。 ... [详细]
  • 我在尝试将组合框转换为具有自动完成功能时遇到了一个问题,即页面上的列表框也被转换成了自动完成下拉框,而不是保持原有的多选列表框形式。 ... [详细]
  • 本文详细介绍了如何使用Linux下的mysqlshow命令来查询MySQL数据库的相关信息,包括数据库、表以及字段的详情。通过本文的学习,读者可以掌握mysqlshow命令的基本语法及其常用选项。 ... [详细]
  • HDU 2537 键盘输入处理
    题目描述了一个名叫Pirates的男孩想要开发一款键盘输入软件,遇到了大小写字母判断的问题。本文提供了该问题的解决方案及实现方法。 ... [详细]
  • selenium通过JS语法操作页面元素
    做过web测试的小伙伴们都知道,web元素现在很多是JS写的,那么既然是JS写的,可以通过JS语言去操作页面,来帮助我们操作一些selenium不能覆盖的功能。问题来了我们能否通过 ... [详细]
  • 本文由公众号【数智物语】(ID: decision_engine)发布,关注获取更多干货。文章探讨了从数据收集到清洗、建模及可视化的全过程,介绍了41款实用工具,旨在帮助数据科学家和分析师提升工作效率。 ... [详细]
  • 如何使用Maven将依赖插件一并打包进JAR文件
    本文详细介绍了在使用Maven构建项目时,如何将所需的依赖插件一同打包进最终的JAR文件中,以避免手动部署依赖库的麻烦。 ... [详细]
  • iOS如何实现手势
    这篇文章主要为大家展示了“iOS如何实现手势”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“iOS ... [详细]
author-avatar
难得有人待我好_212
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有