既然有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结构编写的功能相同的两段代码:
if-else 结构测试代码
switch-case 结构测试代码
具体执行功能为:传入for循环次数、要判断的值,代码分别根据传入值进入相应代码块,然后继续循环,不做其他操作(其实上面代码可以进行优化,为了介绍方便,不做优化)。上述两段代码分别执行完成后看下程序的执行时间。首先上一下我电脑的配置图:
打开UC浏览器 查看更多精彩图片
然后首先分别判断输入值为5,两段代码分别运行1亿次执行时间分别如下:
这里大家只看时间值得user那行(第二行),看出差距来了吧,if结构耗费的时间是switch结构的3倍!下面我们再判断值9,分别运行1亿次看下结果:
差距很明显,if结构对值9(if结构中排列靠后的值)比对值5(if结构中排列较前的值)判断时间明显长很多,而switch结构对数值在代码中的排列前后顺序似乎不是特别明显,if结构相对于switch结构的差距更大了!是什么原因造成的这种结果呢?下面我们在arm平台下,看下if结构和switch结构产生的反汇编代码是什么样子的?
我们通过下述命令(有关linux的命令,本号后续会推出《手把手教你学linux》系列,敬请关注),生成反汇编文件:
看下if结构和swtich结构生成的for循环汇编代码段是什么样子的:
if结构:
if-else 结构反汇编结果
switch结构:
switch-case 结构反汇编结果
注意我标<<<<的几行,if结构的反汇编代码很长,在这里只截取了判断值0~3的一段,标<<<<的代码表示真正进行数值判断的汇编代码,可以看到:if结构的汇编代码(也就是机器所做的动作)是将接收到的实参值与程序当中的值(按值在代码中的排列顺序)挨个进行比较,这就是说,如果要比较的是9,if结构就需要比较10次才会命中。反过来看下switch结构,switch结构很巧妙的运用了“跳转”的思想,对任何一个case值的判断,和值在代码中的排列顺序无关,都会直接“跳转”到符合条件的case块中,所以,执行速度比if结构快得多,而且与值在代码中的排列顺序无关!反汇编代码可以看出,switch结构不仅比if结构执行效率高,占用空间也少!看图:
相信看了上面的介绍,你对if结构和switch结构的优劣性有自己的选择了吧。实际应用当中,我一般遵循以下编码“潜规则”:
1.凡是判断层级达到4层以上的,用switch结构。
2.凡是可能性最大的选项,放在if结构的最顶端。这个思想,也是ARM公司在ARM处理器多级流水线中加入“分支预测”功能的考量之一。
|