读高性能JavaScript编程 第四章 Conditionals

 if else 和 switch    &&    递归  正则表达式

  • if else 和 switch

  通常来讲,if-else 适用于判断两个离散的值或者判断几个不一样的值域。若是判断多于两个离散值,switch
表达式将是更理想的选择。算法

  如同 咱们在写sql 总习惯把能够过滤掉更多的where 放在前面同样,当 if else 判断的离散值较多时也因该这么干。sql

  二分搜索法:shell

 if (value == 0){  //要优化的代码
  return result0; 
} else if (value == 1){ 
  return result1; 
} else if (value == 2){ 
  return result2; 
} else if (value == 3){ 
  return result3; 
} else if (value == 4){ 
  return result4; 
} else if (value == 5){ 
  return result5; 
} else if (value == 6){ 
  return result6; 
} else if (value == 7){ 
  return result7; 
} else if (value == 8){ 
  return result8; 
} else if (value == 9){ 
  return result9; 
} else { 
  return result10; 
} 
 if (value < 6){ //二分搜索法
  if (value < 3){ 
    if (value == 0){ 
      return result0; 
    } else if (value == 1){ 
      return result1; 
    } else { 
      return result2; 
    } 
  } else { 
    if (value == 3){ 
      return result3; 
    } else if (value == 4){ 
      return result4; 
    } else { 
      return result5; 
    } 
  } 
} else { 
  if (value < 8){ 
    if (value == 6){ 
      return result6; 
    } else { 
      return result7; 
    } 
  } else { 
    if (value == 8){ 
      return result8; 
    } else if (value == 9){ 
      return result9; 
    } else { 
      return result10; 
    } 
  } 
} 

代码很简单 ,效果却很明显.浏览器

  查表法:安全

 //define the array of results 
var results = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10] 
//return the correct result 
return results[value]; 

更加简单暴力。函数

 

  • 递归

引用:性能

  JavaScript引擎所支持的递归数量与 JavaScript调用栈大小直接相关。只有 Internet Explorer例外,它的
调用栈与可用系统内存相关,其余浏览器有固定的调用栈限制。大多数现代浏览器的调用栈尺寸比老式浏
览器要大(例如 Safari 2调用栈尺寸是 100)。图 4-2 显示出主流浏览器的调用栈大小。学习

关于调用栈溢出错误,最使人感兴趣的部分大概是:在某些浏览器中,他们的确是 JavaScript 错误,可
以用一个 try-catch 表达式捕获。异常类型因浏览器而不一样。在 Firefox 中,它是一个 InternalError;在 Safari
和 Chrome 中,它是一个 RangeError;在 Internet Explorer中抛出一个通常性的 Error类型。(Opera 不抛出
错误;它终止 JavaScript引擎)。这使得咱们可以在 JavaScript 中正确处理这些错误:
try {
  recurse();
} catch (ex){
  alert("Too much recursion!");
}优化

  若是无论它,那么这些错误将像其余错误同样冒泡上传(在 Firefox中,它结束于 Firebug 和错误终端;
在 Safari/Chrome 中它显示在 JavaScript 终端上),只有 Internet Explorer例外。IE 不会显示一个 JavaScript
错误,可是会弹出一个提示堆栈溢出信息的对话框。

  大多数调用栈错误与递归有关。常见的栈溢出缘由是一个不正确的终止条件,因此定位模式
错误的第一步是验证终止条件。若是终止条件是正确的,那么算法包含了太多层递归,为了可以安全地在
浏览器中运行,应当改用迭代,制表,或二者兼而有之。

   任何能够用递归实现的算法均可以用迭代实现。迭代算法一般包括几个不一样的循环,分别对应算法过程

的不一样方面,也会致使本身的性能为题。可是,使用优化的循环替代长时间运行的递归函数能够提升性能,
由于运行一个循环比反复调用一个函数的开销要低。

优化递归的方案 制表

  一个经典的案例:

 function factorial(n){ 
  if (n == 0){ 
    return 1; 
  } else { 
    return n * factorial(n-1); 
  } 
} 
var fact6 = factorial(6); //factorial 计算阶乘
var fact5 = factorial(5); 
var fact4 = factorial(4); 

  此代码生成三个阶乘结果,factorial()函数总共被调用了 18次。此代码中最糟糕的部分是,全部必要的
计算已经在第一行代码中执行过了。由于 6 的阶乘等于 6乘以 5 的阶乘,因此 5的阶乘被计算了两次。更
糟糕的是,4的阶乘被计算了三次。更为明智的方法是保存并重利用它们的计算结果,而不是每次都从新
计算整个函数。好比这样:

 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]; 
}

  var fact6 = memfactorial(6);
  var fact5 = memfactorial(5);
  var fact4 = memfactorial(4);

 //总共只调用 memfactorial()函数八次

这样未免太过于繁琐,若是把制表的过程封装起来好比这样:

 function memoize(fundamental, cache){ 
  cache = cache || {}; 
  var shell = function(arg){ 
    if (!cache.hasOwnProperty(arg)){ 
      cache[arg] = fundamental(arg); 
    } 
    return cache[arg]; 
  }; 
  return shell; 
} 
 //memoize the factorial function 
var memfactorial = memoize(factorial, { "0": 1, "1": 1 }); 
//call the new function 
var fact6 = memfactorial(6); 
var fact5 = memfactorial(5); 
var fact4 = memfactorial(4); 

须要提醒的是:当一个通用制表函数存在显著性能问题时,最好在这些函数中人工实现制表法。

 最后:运行的代码总量越大,使用这些策略所带来的性能提高就越明显。 代码全是copy书上的,因此强烈建议直接去看书而不是看我罗里吧嗦的几个字总结。

下一章将学习字符串和正则表达式很期待。

相关文章
相关标签/搜索