【发布时间】:2018-04-15 20:06:26
【问题描述】:
我有一个switch 案例程序:
升序切换案例:
int main()
{
int a, sc = 1;
switch (sc)
{
case 1:
a = 1;
break;
case 2:
a = 2;
break;
}
}
代码汇编:
main:
push rbp
mov rbp, rsp
mov DWORD PTR [rbp-4], 1
mov eax, DWORD PTR [rbp-4]
cmp eax, 1
je .L3
cmp eax, 2
je .L4
jmp .L2
.L3:
mov DWORD PTR [rbp-8], 1
jmp .L2
.L4:
mov DWORD PTR [rbp-8], 2
nop
.L2:
mov eax, 0
pop rbp
ret
降序切换案例:
int main()
{
int a, sc = 1;
switch (sc)
{
case 2:
a = 1;
break;
case 1:
a = 2;
break;
}
}
代码汇编:
main:
push rbp
mov rbp, rsp
mov DWORD PTR [rbp-4], 1
mov eax, DWORD PTR [rbp-4]
cmp eax, 1
je .L3
cmp eax, 2
jne .L2
mov DWORD PTR [rbp-8], 1
jmp .L2
.L3:
mov DWORD PTR [rbp-8], 2
nop
.L2:
mov eax, 0
pop rbp
ret
这里,升序顺序比降序顺序产生更多的组装。
那么,如果我有更多的 switch case,那么 case 的顺序会影响性能吗?
【问题讨论】:
-
讨论非优化代码生成指令的数量是完全没有意义的。请注意,这些示例甚至不等效,因为您在它们之间分配了不同的数字。还有,这跟 C99 和 C11 有什么关系?
-
您忘记说明您的平台、编译器和优化设置,以及性能对您的重要性,以及您正在开发的代码类型和大小。如果您愿意花费 20 万欧元来获得几个百分比的性能,那么您也应该这么说。
-
查看一个关于 if 语句排序的非常相似的问题:stackoverflow.com/questions/46833310/…
-
要模拟一个输入不是编译时常量的真实案例,请使用
int foo(int sc){ ...; return a; }。这是在带有 gcc 和 clang-O3 -mtune=intel: godbolt.org/g/anj5Tu 的 Godbolt 上。有趣的是,clang5.0 使用 cmov 链(因为我添加了一个a=-1默认值,而不是在 sc 不是 0 或 1 时返回未初始化的a。当然,在实际用例中,使用 @987654332 的代码@ 将混入其中,例如if (a == 1)稍后可能实际上只是在sc上分支。 -
虽然有点明显,但应该注意的是,通常,由于失败,
case语句的顺序也会改变程序行为,除非每个case都以@ 结尾987654337@(恰好在示例中)。
标签: c performance gcc switch-statement