参考高性能javascript
for in 循环 使用它可以遍历对象的属性名,但是每次的操作都会搜索实例或者原型的属性 导致使用for in 进行遍历会产生更多的开销
书中提到不要使用for in 遍历数组
1 首先for in 会查找原型链上的属性
var arr = [1,2,3]; Array.prototype.a = "test"; for(var i in arr) { console.log(i); console.log(typeof i); }//在这里例子中会发现属性的字段是string 并且a也会作为结果输出 (可以通过hasOwnProperty()进行过滤原型的属性)
var arr = [1,2,3]; Array.prototype.a = "test"; for(var i = 0,len = arr.length;i < len;i+=1) { console.log(i); console.log(typeof i); }//在这个例子中每个i都是number 并且a不会作为结果输出
如何提高循环的整体性能
(1)减少或者优化每次迭代处理的事务 缓存循环中不变的值(不一定是数组的长度 就是不要在循环中不断的去查找一个固定的值 ) 如果数组项的顺序与执行的任务无关,可以使用从后往前处理这种方案,这样就减少了每次跟迭代次数进行比较的这次操作,也优化了性能
(2)减少迭代的次数
在一次迭代中执行多次迭代 能从整体上减少循环迭代的次数
var iterations = Math.floor(items.length/8), startAt = items.length%8, i = 0; console.time("a"); 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);
在使用这种模式的情况下 在次数不够高的时候(比如10000) 我发现这种模式的速度并没有比传统的循环处理快 反而慢 当数量级上来(100000)的时候 的确提升了性能
优化条件语句
根据情景选择合适的条件语句
(1)通常来说if else更适合两个离散值或者几个不同的值域的情况 当条件多于两个离散值的时候,switch语句是更加的选择
(2)优化if else 确保最可能出现的分支放在首位 在if else 的分支中在进行if else的判断 思路都是尽快到达条件的分支
使用Memoization
思路就是缓存之前一次计算的结果供下一次计算使用,在递归算法中常用的技术
function factorial(n) { if(n == 0) { return 1; } else { return n*factorial(n-1); } } console.time("a"); factorial(16); factorial(11); factorial(10); memfactorial(10); memfactorial(10); memfactorial(10); memfactorial(10); console.timeEnd("a"); function memfactorial(n) { if(!memfactorial.cache) { memfactorial.cache = { "0":1, "1":1 }; } if(!memfactorial.cache.hasOwnProperty(n)) { memfactorial.cache[n] = n*memfactorial(n-1); } return memfactorial.cache[n]; } console.time("b"); memfactorial(16); memfactorial(11); memfactorial(10); memfactorial(10); memfactorial(10); memfactorial(10); console.timeEnd("b");
由于我们缓存了之前计算的结果 在后面多次需要这个结果的时候 会很大程度的提高性能(我发现当不是多次需要之前的计算的结果的时候 性能反而没有提升 js引擎性能的提高 和属性的查找也需要耗费一些性能)