在C中切换(){case:}性能

Cya*_*yan 5 c performance switch-statement

可能重复:
为什么切换/案例而不是If/Else如果?

我想了解switch() case:C语句如何被编译器转换为汇编程序操作码.

具体来说,我有兴趣了解一系列if then else分支的差异.

性能比较是主要议题.

关于词汇表的几句话:我熟悉汇编程序的主要概念,很久以前就用汇编程序编写了更简单的系统,但现在肯定没有关于x86汇编程序语义的东西.因此直接汇编器输出将没有用.伪代码是首选.

Jon*_*Jon 6

编译器可以决定将它实现为等效的if/else if语句系列,或者它可以决定使用分支表来优化它。这取决于几个参数,例如分支数和包括您检查的所有值的最小范围的大小。

更新:我记得在某处读到过,通常编译器不会费心创建分支表,除非至少有 4 个或更多的 switch case;Stephane Rouberol下面的信息性评论专门记录了如何为 GCC 配置此阈值。

  • 来自 gcc v4.7.2 发行说明:添加了对新参数 --param case-values-threshold=n 的支持,以允许用户控制将 switch 语句作为一系列 if 语句和使用跳转表之间的截止时间。 (3认同)

Art*_*Art 5

根据编译器中的各种启发式方法,生成的代码最终可能只是一个简单的"if else if"语句链.在某些情况下,当案例的空间很小时,编译器可以创建一个跳转表,例如:

switch (foo) {
case 0:
    a();
case 1:
    b();
case 2:
    c();
case 3:
    d();
default:
    e();
}
Run Code Online (Sandbox Code Playgroud)

可以翻译成:

if (foo < 0 || foo > 3) goto label_default;
else goto internal_jump_table[foo];

internal_jump_table = { label_0, label_1, label_2, label_3 };
label_0: a();
label_1: b();
label_2: c();
label_3: d();
label_default: e();
Run Code Online (Sandbox Code Playgroud)

还有其他优化可以完成.编译器可以构建if语句的层次结构,以便二进制搜索正确的值,而不是检查是否相等.或者你可能有一堆值适当的跳转表和一些正常搜索完成的异常值.或者只是两个跳转表.