c++ - c 切换和跳转表

标签 c++ switch-statement jump-table

据我了解,c/c++ 中的 switch 语句有时会编译为跳转表。 我的问题是,是否有任何经验法则可以确保这一点?

在我的例子中,我正在做这样的事情:

enum myenum{
MY_CASE0= 0,
MY_CASE0= 1, 
.
.
.
};

switch(foo)
{
  case MY_CASE0:
  //do stuff
  break;
  case MY_CASE1:
  //do stuff
  break;
 .
 .
 .
}

我按顺序涵盖了从 1 到 n 的所有情况。可以安全地假设它将编译为跳转表吗? 原始代码是一个又长又乱的 if else 语句,所以至少我获得了一些可读性。

最佳答案

一个好的编译器可以而且会在跳转表、链式 if/else 或组合之间进行选择。设计不佳的编译器可能不会做出这样的选择 - 甚至可能为开关 block 生成非常糟糕的代码。但是任何体面的编译器都应该为开关 block 生成高效的代码。

这里的主要决定因素是当数字相距很远时编译器可能会选择 if/else [并且不是平凡地(例如除以 2、4、8、16、256 等)更改为更接近的值],例如

 switch(x)
 {
    case 1:
     ...
    case 4912:
     ...
    case 11211:
     ...
    case 19102:
     ...
 }

需要至少 19102 * 2 字节的跳转表。

另一方面,如果数字靠得很近,编译器通常会使用跳转表。

即使是 if/else 类型的设计,它通常也会进行“二分搜索”——如果我们采用上面的示例:

 if (x <= 4912)
 {
     if (x == 1)
     {
        ....
     }
     else if (x == 4912)
     {
         .... 
     }
 } else {
     if (x == 11211)
     {
         ....
     }
     else if (x == 19102)
     {
         ...
     }
 }

如果我们有很多情况,这种方法会嵌套得很深,人类可能会在三到四个深度层次后迷失方向(请记住,每个 if 都从范围中间的某个点开始),但是它减少了 log2(n) 的测试次数,其中 n 是选择的数量。它肯定比

的幼稚方法有效得多
if (x == first value) ... 
else if (x == second value) ... 
else if (x == third value) ... 
..
else if (x == nth value) ... 
else ... 

如果将某些值放在 if-else 链的开头,这可能会稍微好一些,但前提是您可以在运行代码之前确定最常见的值。

如果性能对您的情况至关重要,那么您需要对这两个备选方案进行基准测试。但我的猜测是,将代码编写为开关将使代码更清晰,同时运行速度至少一样快,如果不是更快的话。

关于c++ - c 切换和跳转表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17061967/

相关文章:

java - 在 Java 中实现跳转表

将 x86 程序集跳转表转换为 C

c++ - 初始化字符串 vector 数组时出错

c++ - 如何将文件夹与另一个目录中的一些 .cpp 和 .h 文件链接为虚幻引擎项目的包含路径?

sql-server - 如何在 SQL Server 中使用 Switch

java - switch stat 中有多个 block ?

c - 在 ARM 上的代码内切换 case 跳转表位置

c++ - blast 无法创建单位计数容器

c++ - 如何在不使用数组或任何库函数(任何用于反转的函数)的情况下反转用户输入?

java - 在我的形状计算器 Java 程序中使用带有 Switch/Case 语句的循环