假设我们有以下代码:
switch (currentChar) {
case 'G':
case 'T':
case 'M':
case ';':
case '\r':
case '\n':
doSomething();
break;
}
如果满足第一个条件(currentChar == 'G'
),还会比较以下情况,或者程序直接跳到doSomething()
?
执行速度会更快:switch-case,还是if ||
运算符?
澄清:
如果满足任何条件,我希望doSomething
被执行。我也知道' G'案件将发生在所有案件的99%。如果我把它放在列表的顶部,我可以假设它将作为第一个进行比较吗?
答案 0 :(得分:3)
如果满足第一个条件
(currentChar == 'G')
,还会评估以下情况,或者程序直接跳到doSomething()
?
它会立即跳转到执行doSomething()
执行速度会更快:switch-case,还是if
||
运算符?
我认为它不会对任何体面的现代c ++编译器产生任何影响,并且发出的代码应该相同。
答案 1 :(得分:1)
执行速度会更快:switch-case,或带有||的if操作
转到switch()
。如果你有一个设置值很小的枚举或整数,switch()
通常会创建一个跳转表。
答案 2 :(得分:1)
将currentChar
与'G'
进行比较后,说明会跳至指令doSomething()
。您不能依赖案例的顺序来"优化" switch
。
请注意,顺序的比较不是必需的
switch
可以实现为跳转表,例如:
void foo_switch(char c)
{
switch (c) {
case '0': bar0(); break;
case '1': bar1(); break;
case '2': bar2(); break;
case '3': bar3(); break;
};
}
void foo_if(char c)
{
if (c == '0') {
bar0();
} else if (c == '1') {
bar1();
} else if (c == '2') {
bar2();
} else if (c == '3') {
bar3();
}
}
void foo_table(char c)
{
if ('0' <= c && c <= '3') {
using voidFPtr = void(*)();
voidFPtr funcs[] = {&bar0, &bar1, &bar2, &bar3};
funcs[c - '0']();
}
}
答案 3 :(得分:1)
关于特定代码风格的性能结果的问题几乎总是浪费时间。
以下是gcc5.3在优化传递后处理此代码的方式:
test(char):
cmpb $59, %dil
je .L3
jle .L6
cmpb $77, %dil
je .L3
cmpb $84, %dil
je .L3
cmpb $71, %dil
je .L3
.L1:
rep ret
.L6:
cmpb $10, %dil
je .L3
cmpb $13, %dil
jne .L1
.L3:
jmp doSomething()
我真的不认为你可以在不创建256条目跳转表的情况下更快地编写任何内容,这会在缓存局部性和耗尽方面产生影响。
答案 4 :(得分:0)
如果满足第一个条件(currentChar =='G'),还会评估以下情况,或者程序直接跳转到doSomething()?
在您的示例中,它会立即跳转到doSomething()
。如果您不想有这种行为,那么您需要插入break
语句,如下图所示:
switch (currentChar) {
case 'G': /*things to be done */ break /* This break will take it out of switch*/;
case 'T':
case 'M':
case ';':
case '\r':
case '\n':
doSomething();
break;
}
另请注意,在您的示例中,不需要break
,因为它是switch语句的最后一个语句。有关switch语句的工作示例,请参阅this链接。
执行速度会更快:switch-case,或带有||的if操作
假设您正在使用一个不错的编译器,差异是最小的,因此可以忽略它。如果您需要了解更多细节,请参阅this所以链接。
编辑以供澄清:
如果满足任何条件,我希望
doSomething()
被执行。
是的,根据您的代码,即使只满足其中一个条件,也会执行doSomething()
。
我也知道,'G'案件将在所有案件中占99%。如果我把它放在列表的顶部,我可以假设它将作为第一个进行比较吗?
不会检查剩余的案例。
答案 5 :(得分:0)
如果满足第一个条件(currentChar ==&#39; G&#39;)如下 案例也进行了评估,或者程序直接跳到doSomething()?
直到它找到break
或达到结束为止。
答案 6 :(得分:0)
执行速度会更快:switch-case,或带有||的if操作
您应该担心代码的可读性和可支持性,因此请使用更易读的内容。然后,如果您在优化时遇到程序速度问题。
为了便于阅读 - 当然这是主观的,但是通过切换可以减少冗长的代码,因为您不必多次重复变量名称:
if( currentChar == 'G' || currentChar == 'B' || currentChar == 'C' )
所以我希望在这种情况下切换。
答案 7 :(得分:0)
switch (currentChar) {
case 'G':
case 'T':
case 'M':
case ';':
case '\r':
case '\n':
doSomething();
break;
}
如果doSomething()
为currentChar
,G
,T
,M
,;
或{{}},则会调用\r
{1}}。使用\n
比使用普通switch
更快,因为if
语句通常会优化为跳转表。这就是开关必须以恒定的积分值运行的原因。
答案 8 :(得分:0)
无法保证检查开关盒的顺序。如果表达式没有副作用,也无法保证||
的执行顺序
基本上,如果唯一的区别是时间,那么c ++在as-if规则的基础上不保证任何东西的顺序。