• 高性能javascript学习笔记系列(4) -算法和流程控制


    参考高性能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引擎性能的提高 和属性的查找也需要耗费一些性能)

  • 相关阅读:
    【BZOJ】1620: [Usaco2008 Nov]Time Management 时间管理(贪心)
    【BZOJ】1651: [Usaco2006 Feb]Stall Reservations 专用牛棚(线段树/前缀和 + 差分)
    【BZOJ】1628 && 1683: [Usaco2007 Demo]City skyline 城市地平线(单调栈)
    【BZOJ】1624: [Usaco2008 Open] Clear And Present Danger 寻宝之路(floyd)
    【BZOJ】1622: [Usaco2008 Open]Word Power 名字的能量(dp/-模拟)
    【BZOJ】1634: [Usaco2007 Jan]Protecting the Flowers 护花(贪心)
    【BZOJ】1690: [Usaco2007 Dec]奶牛的旅行(分数规划+spfa)
    【BZOJ】1660: [Usaco2006 Nov]Bad Hair Day 乱发节(单调栈)
    【BZOJ】1642: [Usaco2007 Nov]Milking Time 挤奶时间(dp)
    【BZOJ】1629: [Usaco2007 Demo]Cow Acrobats(贪心+排序)
  • 原文地址:https://www.cnblogs.com/tiantianwaigong/p/5558986.html
Copyright © 2020-2023  润新知