循环处理是最常见的编程模式之一,也是提升性能必须关注的要点之一。
常见的优化方案有:
①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; } }
取某次测试结果:
平均来说,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%)。总的来说,循环次数大的情况下,运行时间确实有提升。取某次结果如下:
没有局部存量存储数组长度时:
有局部变量存储数组长度时:
③减少迭代次数,“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都快。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
- 群星《左耳·听见爱情》星文唱片[WAV+CUE]
- 陈美玲.1987-孤单的心【EMI百代】【WAV+CUE】
- 黄乙玲.2005-甲你作伴【亚律音乐】【WAV+CUE】
- 张雨生.1997-口是心非【丰华】【WAV+CUE】
- 群星《右耳·聆听私语》星文唱片[WAV+CUE]
- VitoCadonau-ramur-encasaveglia(2024)[24-44,1]FLAC
- Mozart--ArthurGrumiaux(2024)[24BT]WAV
- 国风大师纯音系列《付娜广粤古筝》1CD[MP3][364.4MB]
- 国风大师纯音系列《罗晶-古筝情缘》1CD[MP3][75.1MB]
- 国风大师纯音系列《民乐琴王童丽-与古筝的约会》1CD[MP3][166.4MB]
- 刘美君.1993-被你纵坏【SONY】【WAV+CUE】
- 黄鹤翔.1998-爱的咏叹调【中唱】【WAV+CUE】
- 薰妮.1983-梦+淡(2000年永恒真存双碟版)【永恒】【WAV+CUE】
- 方伊琪.1976-时光消逝(2015复黑限量版)【风行】【WAV+CUE】
- 群星.1990-宝丽金影视金曲巡礼【宝丽金】【WAV+CUE】