上文介绍了《随时随地学习C语言之2—main函数的参数argc和argv是啥?》本节一起来讨论下C语言中的分支选择语句if和swtich哪个效率高?

之前学习C语言的时候,我经常有一个疑问,既然有if-else if-else结构的多分支选择语句,C语言为何还要制定switch这种多分支选择语句呢?直到两年前在分析ARM平台C语言反汇编代码的时候,才终于明白了switch-case这种结构存在的意义及价值。一句话来说,就是switch结构产生的机器代码更为精简、CPU执行起来更加高效。switch结构相对于if-else结构的执行效率,选择选项越多,领先越明显。今天,我们分析下ARM平台下(抱歉,我也只会ARM汇编),if-else结构和switch-case结构的差异和差距。

首先,下面两图是分别用if-else和switch-case结构编写的功能相同的两段代码:

c语言switch里怎么用两个if语句 随时随地学习C语言之3(1)

if-else结构

c语言switch里怎么用两个if语句 随时随地学习C语言之3(2)

switch-case结构

具体执行功能为:传入for循环次数、要判断的值,代码分别根据传入值进入相应代码块,然后继续循环,不做其他操作(其实上面代码可以进行优化,为了介绍方便,不做优化)。上述两段代码分别执行完成后看下程序的执行时间。首先上一下我电脑的配置图:

c语言switch里怎么用两个if语句 随时随地学习C语言之3(3)

然后首先分别判断输入值为5,两段代码分别运行1亿次执行时间分别如下:

c语言switch里怎么用两个if语句 随时随地学习C语言之3(4)

这里大家只看时间值得user那行(第二行),看出差距来了吧,if结构耗费的时间是switch结构的3倍!下面我们再判断值9,分别运行1亿次看下结果:

c语言switch里怎么用两个if语句 随时随地学习C语言之3(5)

差距很明显,if结构对值9(if结构中排列靠后的值)比对值5(if结构中排列较前的值)判断时间明显长很多,而switch结构对数值在代码中的排列前后顺序似乎不是特别明显,if结构相对于switch结构的差距更大了!是什么原因造成的这种结果呢?下面我们在arm平台下,看下if结构和switch结构产生的反汇编代码是什么样子的?

我们通过下述命令(有关linux的命令,本号后续会推出《手把手教你学linux》系列,敬请关注),生成反汇编文件:

c语言switch里怎么用两个if语句 随时随地学习C语言之3(6)

看下if结构和swtich结构生成的for循环汇编代码段是什么样子的:

if结构:

c语言switch里怎么用两个if语句 随时随地学习C语言之3(7)

if 结构反汇编代码(部分)

switch结构:

c语言switch里怎么用两个if语句 随时随地学习C语言之3(8)

switch 结构反汇编代码

注意我标<<<<的几行,if结构的反汇编代码很长,在这里只截取了判断值0~3的一段,标<<<<的代码表示真正进行数值判断的汇编代码,可以看到:if结构的汇编代码(也就是机器所做的动作)是将接收到的实参值与程序当中的值(按值在代码中的排列顺序)挨个进行比较,这就是说,如果要比较的是9,if结构就需要比较10次才会命中。反过来看下switch结构,switch结构很巧妙的运用了“跳转”的思想,对任何一个case值的判断,和值在代码中的排列顺序无关,都会直接“跳转”到符合条件的case块中,所以,执行速度比if结构快得多,而且与值在代码中的排列顺序无关!反汇编代码可以看出,switch结构不仅比if结构执行效率高,占用空间也少!看图:

c语言switch里怎么用两个if语句 随时随地学习C语言之3(9)

相信看了上面的介绍,你对if结构和switch结构的优劣性有自己的选择了吧。实际应用当中,我一般遵循以下编码“潜规则”:

1.凡是判断层级达到4层以上的,用switch结构。

2.凡是可能性最大的选项,放在if结构的最顶端。这个思想,也是ARM公司在ARM处理器多级流水线中加入“分支预测”功能的考量之一。

好啦,经过本文的介绍,if结构和switch结构的效率(执行效率、空间效率)你懂了吧~

,