c++ - 编译器优化开关的方式是否与长 if-then-else 链不同?
问题描述
假设我在编译时有 N 个不同的整数值,从 V_1 到 V_N。考虑以下结构:
const int x = foo();
switch(x) {
case V_1: { /* commands for V_1 which don't change x */ } break;
case V_2: { /* commands for V_1 which don't change x */ } break;
/* ... */
case V_N: { /* commands for V_1 which don't change x */ } break;
}
相对
const int x = foo();
if (x == V_1) { /* commands for V_1 which don't change x */ }
else if (x == V_2) { /* commands for V_2 which don't change x */ }
else ...
else if (x == V_N) { /* commands for V_N which don't change x */ }
现代 C++ 编译器是否以不同的方式处理这些?也就是说,他们是否对这些代码结构应用了不同的潜在优化?或者他们是否将它们“规范化”为相同的,然后决定优化(例如是否形成跳转表)?
笔记:
- 我所说的现代 C++ 编译器主要指的是最新版本的 GCC、clang 和 MSVC。ICC 也可能是相关的。
- 请回答关于最大优化级别(
-O3
对于clang和GCC) - ...但是,如果
switch
es 和if-then-else
-chains 的处理在某些优化级别是相同的,而在其他优化级别不同,那也很有趣。 - 我猜答案可能取决于
N
- 如果可能,请给出阈值。
解决方案
Ironically, that is exactly the test I did just a couple of days back for most recent compilers. As it happened, with latest compilers, clang
produces the same assembly for switch
and if
- for small number of cases (below 5) it produces a bunch of direct conditional jumps, while for 5 or more cases it does an indirect table jump.
On the other hand, gcc
treats those differently: it converts switch
to indirect table jump, while a series of if
statements remain a series of conditional direct jumps.
It is also worth noting, that if switch case has "holes" in it (i.e. possible values for control variable which are not covered by case label), it can be still converted into series of conditional direct jumps or indirect table jump, but I wasn't able to figure out the exact formula.
Here is some play code: https://gcc.godbolt.org/z/Lll1Kd
推荐阅读
- webpack - 使用 webpack mini-css-extract-plugin 插件时出错
- c++ - 显式类型转换的 C++ 转换表示法(C 样式转换)和 static_cast 的多种解释
- r - 使用 case_when 填写一个字符串
- apache-kafka - KAFKA - 如何重新平衡可用经纪人的分区
- amazon-web-services - emr-dynamodb-connector 是否并行读取数据
- html - Webkit 任何覆盖用户代理样式表
- javascript - 正则表达式在 cretin 字符后获取多个数字
- javafx - 如何阻止 TextArea 将 Shortcut KeyCombinations 作为 KeyEvents 收听?
- python - 有向线段之间的符号角
- python - 单元测试模拟/覆盖套接字的发送