学写提高性能的代码之流程控制-1

365 阅读3分钟

这是我参与8月更文挑战的第7天,活动详情查看: 8月更文挑战

前言

业务代码开发多了,其实就是在写 if-else

这句话应该还是能获得很多人的认同的,这也从侧面反映出,流程控制在代码中的比重是占一席之地的。因此优化流程控制方面的代码,必然能有效的提升代码运行的速度。


条件判断

条件判断到底是该用if-else还是switch,似乎是所有编程语言都存在的讨论,本文中主要关注的重点是:如何更高效的处理一系列的条件判断,来带来性能的提升。

if-else和switch

通常的if-else条件语句如下:

if(value === 0){

} else if(value === 1){

} else if(value === 2){

} else if(value === 3){

} else {

}

if-else的判断条件中,变量的取值可以是相应的离散值,也可以是不同的区间范围。当变量的取值全部为离散值时,便可将if-else的判断形式改写成switch,代码如下:

switch(value){
  case 0:
    // ...
    break
  case 1:
    // ...
    break
  case 2:
    // ...
    break
  case 3:
    // ...
    break
  default: 
    // ...
}

通常对于多个离散值的取值条件判断,使用switch会比if-else具有更高的性能表现。switch可以清晰的表明判断条件和返回值之间的对应关系,同时switch还可以将不同的条件取值指向相同的处理过程,这也使它具有更好的代码可读性。

如果只有一两个条件的判断,通常if-else处理条件的时间会比switch更快,当判断条件多到两个以上时,因为在大多数时候,switch处理单个条件的时间比if-else更快,所以switch更加合适。

if-else的优化

回到if-else的例子中,如果程序最终的执行路径是最后一个else if子语句,那么当执行到此处之前,其余所有条件判断必然都要经历一遍。这也就是说,匹配最后一个条件的情况,会比之前所有判断条件执行耗时都久。

基于此便有了两种优化方式,第一种优化方式是开发者可以预先预估条件被匹配到的频率,按照频率的降序顺序来排列if-else语句,可以让匹配频率高的条件更快执行,从而在整体上降低程序花费在条件判断上的时间,比如:

if(value === 8){
  // 匹配到8的概率最高
} else if(value === 7){
  // 匹配到7的概率仅次于8
} else if(value === 6){
  // 匹配到6的概率最低
} else {
  // 执行到else中,不需要对于6以外的条件判断
}

第二种优化方式是利用二分法的思路,可能开发人员在编写相应的业务代码时,并不能预先估计出各种条件在多次执行时被匹配到的频率,但却能对取值区间的边界有明确的划分,那么便可以用二分取值范围来降低匹配条件的执行次数,比如:

if(value < 4){
  if(value < 2){
    // 值在小于2时的情况,也可继续二分
  } else {
    // 值在2或3之间
  }
} else {
  if(value < 6){
    // 值在4或5之间
  } else {
    // 值在6到上界之间取值
  }
}

这里使用简单的数字区间划分进行演示,如果放到具体的业务场景中,则实际复杂度会高许多。虽然二分法的思路能够很好地降低条件判断的执行次数,但这样深度嵌套if-else写法的代码可读性会非常低,所以在实际编程中直接套用并不合适,但其二分折半处理的思想还是具有一定借鉴意义的。