为什么说switch比if快

C++的switch语法

在C++中,switch只接受整型常量作为分支的值:



switch (expr) {
case integral-constant :
    \\...
    break;
case integral-constant :
    \\...
    break;
default :
    \\...
    break;
}

这里有几个需要注意的细节:

  • 最好将default分支写出来,即使什么也不做
  • 若分支没有写break语句,那么最好注释为什么这么做
  • 若要在switch内定义变量需要创建一个作用域{},否则从语法上就可以跳过变量的初始化而直接使用变量,这样是不合理的所以编译会直接报错

switch的实现原理

switch的实现利用了跳转表这一数据结构,其实就是一个保存各个分支代码入口地址的数组。与一连串的if/else相比,跳转表的优点就是确定分支代码的时间和分支数量无关,是一个常数
编译器会根据switch的分支数量以及分支对应的值的稀疏程度来决定如何翻译代码。当分支数量较多且值相对集中的时候就会采用跳转表来实现

//原版C++代码
int ans = 0;

switch (n) {
case 100 :
    ans = 0;
    break;

case 102 :
    ans = 2;
    //fall through

case 103 :
    ans = 3;
    break;

case 104 :
    //fall through

case 106 :
    ans = 6;
    break;

default :
    ans = 0;
}

return ans;
//翻译为跳转表的C++代码
//跳转表
static void *jt[7] = {
    &&loc_A, &&loc_def, &&loc_B,
    &&loc_C, &&loc_D, &&loc_def,
    &&loc_D
};

//对分支对应的值做简单的坐标变换
unsigned index = n - 100;

int ans = 0;

//default分支
if (index > 6) {
    goto def;
}

//进行分支跳转
goto &jt[index];

//case 100
loc_A :
    ans = 0;
    goto done;

//case 102
loc_B :
    ans = 2;
    //fall through

loc_C :
    ans = 3;
    goto done;

//case 104 106
loc_D :
    ans = 6;
    goto done;

loc_def :
    ans = 0;

done :
    return ans;
  • 素材来自«深入理解计算机系统»
posted @ 2019-12-10 23:56  HachikoT  阅读(513)  评论(0编辑  收藏  举报