代码汇编对比
● switch:跳转表直接定位分支
● if-else:依次逐个条件比较
核心差异:switch 计算偏移直接跳转;if-else 顺序依次判断
switch 反汇编底层原理(跳转表模式)
- 变量预处理 把字符 / 变量转为整型保存,减去最小 case 常量,算出相对偏移
例:case 'A'(0x41)~'E',输入字符 - 'A',得到 0、1、2、3、4 - 范围校验 使用ja指令判断偏移是否超出最大跨度,超出直接跳到default
- 跳转表机制 O (1) 指令:jmp edx\*4 + 基地址
○ 跳转表:一块连续内存,存放每个 case 入口地址
○ 不管匹配哪个 case,核心指令步数固定,耗时几乎不变
○ 代价:占用额外内存存放跳转表
⚠️前提:case 值连续 / 近似连续,编译器才会生成跳转表;离散 case 不会生成跳转表,此时 switch 效率和 if-else 差不多
if-else 底层原理
- 顺序比较 O (n) 从第一个 if 开始,cmp + jne逐个判断,不命中就继续下一条
- 最坏情况:目标分支在最后,全部条件都要比较一遍
- 缺点:多次重复加载变量,分支越靠后,执行指令越多,耗时线性增加
总结
| switch(生成跳转表时) | if-else | |
|---|---|---|
| 跳转方式 | 计算偏移,查表跳转 | 顺序条件判断 |
| 时间复杂度 | O(1) | O(n) |
| 适用场景 | 多分支、case 值连续(枚举 / ASCII) | 分支少、case 数值离散 |
| 代价 | 占用额外内存(跳转表) | 不额外占用空间 |
工程结论
- case 数量≥4,并且 case 数值连续 → 优先 switch,性能优势明显
- case 数值零散不连续 → 编译器不生成跳转表,switch 无性能优势
- 分支很少(2~3 个),if-else 和 switch 性能差距几乎感知不到
- 验证方式:Debug 模式看反汇编,确认是否生成跳转表
补充
● switch 不是天生就快,跳转表是编译器优化产物
● 字符 case 本质也是整型比较(用 ASCII 码),适合做 switch 跳转表优化