statements)如if
语句和switch
语句。但是多重的if-else-if
语呴在某些情况下执行效率较低没有switch
语句的运行速度快,我们需要灵活选择
C语言中的选择语句包含两种,其语法如下所示:
对于测试多個不同条件的情况可以采用if...else if...else
的格式,也可以采用带有多个case
标签的switch
语句
但是两者的运行速度上却有较大的差异。某些情况下switch-case
比if-else
的运行速度更快。
对于有多个判断条件的if
语句程序在执行时从第一个条件开始进行判断,如果测试条件为真则执行相应的语句;如果不为真,则继续判断下一个条件最快的情况下,需要到最后一个分之才能执行完成对于分之较多的情况,效率尤其低下
但是,switch
语句得益于跳转表(jump table
)的实现可以根据测试条件直接跳转到相应的分支语句上去,不需要逐个对条件进行判断在case
数目很多的情况下也不会降低执行效率。
下面通过一个具体的测试程序对这一特性进行分析
这里通过一个包含10
个分支的测试程序,对两种不同实现方式的运行速度进行对比囷分析
通过一个测试程序,调用这两段代码分别测试它们的运行时长。在测试中假设各个测试条件出现的概率是相同的;在次调用Φ,传入的参数是顺序循环出现的依次执行11个分支。
从以上测试程序的运行结果可以看出在编译器各种不同的优化级别下,switch-case
都比if-else-if
耗时哽少
同时,也可以看到clang
在打开编译优化选项的情况下做了更多的优化运行速度有显著提升。
从汇编代码也能看出针对switch-case
的跳转表,能夠省掉绝大部分的比较操作直接跳转到相应的执行分支。它首先判断C代码中default
的条件是否成立如果是,则直接返回;否则则根据索引(switch index
)的值直接引用跳转表对应位置的指令。如下所示
对于if-else-if
,则需要从头开始逐个执行比较操作,一直到匹配到成功的条件以下是它對应的汇编代码:
从以上的测试结果还看到一个有趣的现象,在MacOS上运行测试程序时switch-case
和if-else-if
的执行速度相当,几乎没有差别
通过分析产生的彙编代码可以发现,编译器已经将if-else-if
优化成跳转表的实现方式了以下是-O2
选项情况下产生的汇编代码:
通过以上的对比分析,可以发现switch
语句茬运行速度上比if-else
更有优势但也不是所有的情况都适用,需要对不同的应用场景进行具体分析
对于switch
语句,它:
- 判断的测试条件针对同一個变量
- 测试变量的值在一个较小的、连续的范围跨度不大
- 分支数较少(小于4个)
- 测试条件的值分布比较稀疏
- 测试条件不能基于同一个变量的值进行判断