C++ switch 语句评估
C++ switch statement evaluation
假设我们有以下代码:
switch (currentChar) {
case 'G':
case 'T':
case 'M':
case ';':
case '\r':
case '\n':
doSomething();
break;
}
如果满足第一个条件(currentChar == 'G'
)是否还要比较下面的情况,或者程序直接跳转到doSomething()
?
什么执行起来更快:switch-case,还是带有 ||
运算符的 if?
澄清:
如果满足任何条件,我希望执行 doSomething
。我也知道 'G' 情况将在所有情况中的大约 99% 发生。如果我把它放在列表的顶部,我可以假设它会被作为第一个进行比较吗?
If the first condition is met (currentChar == 'G')
are the following cases also evaluated, or the program jumps straight to doSomething()
?
会立即跳转执行doSomething()
What would be faster to execute: the switch-case, or an if with ||
operator?
我认为它对任何像样的现代 c++ 编译器没有任何影响,发出的代码应该完全相同。
What would be faster to execute: the switch-case, or an if with || operator?
争取 switch()
。如果您有一个设置了小值的枚举或整数,switch()
通常会创建一个跳转 table。
If the first condition is met (currentChar == 'G') are the following cases also evaluated, or the program jumps straight to 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 语句的最后一条语句。请参阅 this link 以获取 switch 语句的工作示例。
What would be faster to execute: the switch-case, or an if with || operator?
假设您使用的是一个不错的编译器,差异很小,可以忽略不计。请参阅 this 所以 link,以防您需要了解更多细节。
编辑以供澄清:
I want doSomething()
to be executed if any of the conditions is met.
是的,根据您的代码,即使只满足其中一个条件,也会执行 doSomething()
。
I also know that the 'G' case will occur in some 99% of all cases. Can I assume that it will be compared as the first if I put it on top of the list?
其余情况将不检查。
If the first condition is met (currentChar == 'G') are the following
cases also evaluated, or the program jumps straight to doSomething()?
它一直掉下去,直到找到 break
或到达终点。
一旦 currentChar
与 'G'
进行比较,指令跳转到指令 doSomething()
。您不能依赖案例的顺序 "optimize" switch
.
请注意,比较不需要按顺序进行。
switch
可以实现为跳转 table 例如:
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']();
}
}
What would be faster to execute: the switch-case, or an if with || operator?
您应该担心代码的可读性和可支持性,因此请使用对您而言更具可读性的内容。然后,如果您对程序速度有疑问,请进行优化。
为了可读性——当然这是主观的,但是使用 switch 可以减少冗长的代码,因为您不必多次重复变量名:
if( currentChar == 'G' || currentChar == 'B' || currentChar == 'C' )
所以我更愿意在这种情况下切换。
switch (currentChar) {
case 'G':
case 'T':
case 'M':
case ';':
case '\r':
case '\n':
doSomething();
break;
}
这使得 doSomething()
在 currentChar
为 G
、T
、M
、;
、\r
时被调用或 \n
。使用 switch
比使用普通的 if
更快,因为 switch
语句通常被优化为跳转表。这就是为什么开关必须在恒定的整数值上运行。
无法保证 switch case 中的检查顺序。如果表达式没有副作用,也无法保证 ||
的执行顺序。
基本上,如果唯一的区别是时间,C++ 不保证任何东西的顺序,基于 as-if 规则。
关于特定代码风格的性能结果的问题几乎总是在浪费时间。
以下是 gcc5.3 在优化通过后如何处理这段代码:
test(char):
cmpb , %dil
je .L3
jle .L6
cmpb , %dil
je .L3
cmpb , %dil
je .L3
cmpb , %dil
je .L3
.L1:
rep ret
.L6:
cmpb , %dil
je .L3
cmpb , %dil
jne .L1
.L3:
jmp doSomething()
我真的不认为如果不创建 256 条目跳转 table,你可以写得更快,这将在缓存位置和耗尽方面产生自己的后果。
假设我们有以下代码:
switch (currentChar) {
case 'G':
case 'T':
case 'M':
case ';':
case '\r':
case '\n':
doSomething();
break;
}
如果满足第一个条件(currentChar == 'G'
)是否还要比较下面的情况,或者程序直接跳转到doSomething()
?
什么执行起来更快:switch-case,还是带有 ||
运算符的 if?
澄清:
如果满足任何条件,我希望执行 doSomething
。我也知道 'G' 情况将在所有情况中的大约 99% 发生。如果我把它放在列表的顶部,我可以假设它会被作为第一个进行比较吗?
If the first condition is met
(currentChar == 'G')
are the following cases also evaluated, or the program jumps straight todoSomething()
?
会立即跳转执行doSomething()
What would be faster to execute: the switch-case, or an if with
||
operator?
我认为它对任何像样的现代 c++ 编译器没有任何影响,发出的代码应该完全相同。
What would be faster to execute: the switch-case, or an if with || operator?
争取 switch()
。如果您有一个设置了小值的枚举或整数,switch()
通常会创建一个跳转 table。
If the first condition is met (currentChar == 'G') are the following cases also evaluated, or the program jumps straight to 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 语句的最后一条语句。请参阅 this link 以获取 switch 语句的工作示例。
What would be faster to execute: the switch-case, or an if with || operator?
假设您使用的是一个不错的编译器,差异很小,可以忽略不计。请参阅 this 所以 link,以防您需要了解更多细节。
编辑以供澄清:
I want
doSomething()
to be executed if any of the conditions is met.
是的,根据您的代码,即使只满足其中一个条件,也会执行 doSomething()
。
I also know that the 'G' case will occur in some 99% of all cases. Can I assume that it will be compared as the first if I put it on top of the list?
其余情况将不检查。
If the first condition is met (currentChar == 'G') are the following cases also evaluated, or the program jumps straight to doSomething()?
它一直掉下去,直到找到 break
或到达终点。
一旦 currentChar
与 'G'
进行比较,指令跳转到指令 doSomething()
。您不能依赖案例的顺序 "optimize" switch
.
请注意,比较不需要按顺序进行。
switch
可以实现为跳转 table 例如:
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']();
}
}
What would be faster to execute: the switch-case, or an if with || operator?
您应该担心代码的可读性和可支持性,因此请使用对您而言更具可读性的内容。然后,如果您对程序速度有疑问,请进行优化。
为了可读性——当然这是主观的,但是使用 switch 可以减少冗长的代码,因为您不必多次重复变量名:
if( currentChar == 'G' || currentChar == 'B' || currentChar == 'C' )
所以我更愿意在这种情况下切换。
switch (currentChar) {
case 'G':
case 'T':
case 'M':
case ';':
case '\r':
case '\n':
doSomething();
break;
}
这使得 doSomething()
在 currentChar
为 G
、T
、M
、;
、\r
时被调用或 \n
。使用 switch
比使用普通的 if
更快,因为 switch
语句通常被优化为跳转表。这就是为什么开关必须在恒定的整数值上运行。
无法保证 switch case 中的检查顺序。如果表达式没有副作用,也无法保证 ||
的执行顺序。
基本上,如果唯一的区别是时间,C++ 不保证任何东西的顺序,基于 as-if 规则。
关于特定代码风格的性能结果的问题几乎总是在浪费时间。
以下是 gcc5.3 在优化通过后如何处理这段代码:
test(char):
cmpb , %dil
je .L3
jle .L6
cmpb , %dil
je .L3
cmpb , %dil
je .L3
cmpb , %dil
je .L3
.L1:
rep ret
.L6:
cmpb , %dil
je .L3
cmpb , %dil
jne .L1
.L3:
jmp doSomething()
我真的不认为如果不创建 256 条目跳转 table,你可以写得更快,这将在缓存位置和耗尽方面产生自己的后果。