if...else改写为switch...case 真的有必要吗?

968 阅读2分钟

switch...case 比 if...else 效率更高?

在很多人的概念里,switch 的执行效率是比 if/else 高的。

在很多人的概念里,if/else 是用了多次比较判断,而 switch 是用的跳转表一次跳转。

在很多人的概念里,switch写法比if...else更有逼格

其实无非就是两点嘛

可读性: switch和if..else if是半斤八两的写法,可读性差不多,并没有谁好谁坏。switch显得更整齐,if else可以更灵活。分支数目过多时,都会容易藏入bug,不是把if换成switch就能解决问题的。

性能:性能也是要分情况定的,没有说把if改成switch来解决性能问题的。

测试图表

有人做过这样的测试,并且有一张非常清楚的图

image.png

图中可以看到:

  1. 100个case以内,if..else 和 switch 性能差别微乎其微
  2. 在大于450个case的时候,switch才开始有明显的性能差距。450个case显然实际开发中并不会出现这种情况。

例子

// 例1
switch(x) {
case 1: // do something
case 2: // do something
case 3: // do something
// ...
case 32: // do something
default: // do something
}

这种case范围集中,用跳转表确实比用if/else 判断要好一些,编译器只需要使用一个大小为32的跳转表,跳转前判断一下是否在表范围内,然后查表一次就可。

// 例2
switch(x) {
case 1: // do something
case 12: // do something
case 123: // do something
// ...
case 123456789: // do something
default: // do something
}

这种case比较分散,如果使用跳转表的话,表要开多大、跳转要几次?如果我们希望仍然跳转一次,那么表的大小就要开的很大。实际上,编译器在面临这种情况时的处理方式是 —— 存入一个小的数组然后使用二分查找的方式来进行查询,实际查表 logN 次。

// 例3
switch(x) {
case 1: // do something
case 2: // do something
case 3: // do something
default: // do something
}

case很少,编译器会直接转化成if/else来判断,没有区别。

总结

实际开发中判断分支正常来讲不会很多,当前情况若switch写法会比if...else整齐很多可以说优先switch

个人认为没必要在这种小细节上过度优化