的计算成本是否有任何差异
if(something){
return something;
}else{
return somethingElse;
}
和
if(something){
return something;
}
//else (put in comments for readibility purposes)
return somethingElse;
理论上我们有命令(其他),但它似乎不应该产生实际差异。
编辑: 运行不同设置大小的代码后,我发现实际上存在差异,没有其他代码似乎效率提高了1.5%。但它很可能取决于编译器,正如下面许多人所说的那样。我在代码上测试了它:
int withoutElse(bool a){
if(a)
return 0;
return 1;
}
int withElse(bool a){
if(a)
return 0;
else
return 1;
}
int main(){
using namespace std;
bool a=true;
clock_t begin,end;
begin= clock();
for(__int64 i=0;i<1000000000;i++){
a=!a;
withElse(a);
}
end = clock();
cout<<end-begin<<endl;
begin= clock();
for(__int64 i=0;i<1000000000;i++){
a=!a;
withoutElse(a);
}
end = clock();
cout<<end-begin<<endl;
return 0;
}
检查从1 000 000到1 000 000 000的循环,结果始终不同
编辑2: 汇编代码(再一次,使用Visual Studio 2010生成)也显示出很小的差异(显然,我对汇编程序不好:()
?withElse@@YAH_N@Z PROC ; withElse, COMDAT
; Line 12
push ebp
mov ebp, esp
sub esp, 192 ; 000000c0H
push ebx
push esi
push edi
lea edi, DWORD PTR [ebp-192]
mov ecx, 48 ; 00000030H
mov eax, -858993460 ; ccccccccH
rep stosd
; Line 13
movzx eax, BYTE PTR _a$[ebp]
test eax, eax
je SHORT $LN2@withElse
; Line 14
xor eax, eax
jmp SHORT $LN3@withElse
; Line 15
jmp SHORT $LN3@withElse
$LN2@withElse:
; Line 16
mov eax, 1
$LN3@withElse:
; Line 17
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret 0
?withElse@@YAH_N@Z ENDP ; withElse
和
?withoutElse@@YAH_N@Z PROC ; withoutElse, COMDAT
; Line 4
push ebp
mov ebp, esp
sub esp, 192 ; 000000c0H
push ebx
push esi
push edi
lea edi, DWORD PTR [ebp-192]
mov ecx, 48 ; 00000030H
mov eax, -858993460 ; ccccccccH
rep stosd
; Line 5
movzx eax, BYTE PTR _a$[ebp]
test eax, eax
je SHORT $LN1@withoutEls
; Line 6
xor eax, eax
jmp SHORT $LN2@withoutEls
$LN1@withoutEls:
; Line 7
mov eax, 1
$LN2@withoutEls:
; Line 9
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret 0
?withoutElse@@YAH_N@Z ENDP ; withoutElse
答案 0 :(得分:4)
它通常是不同的,但编译器可能决定在两种情况下都执行相同的跳转(它实际上总是这样做)。 查看编译器执行操作的最佳方法是读取汇编程序。假设您正在使用gcc,可以尝试使用
gcc -g -c -fverbose-asm myfile.c; objdump -d -M intel -S myfile.o > myfile.s
创建了汇编程序/ c代码的混合,并使工作在开始时更容易。
至于你的例子:
<强> CASE1 强>
if(something){
23: 83 7d fc 00 cmp DWORD PTR [ebp-0x4],0x0
27: 74 05 je 2e <main+0x19>
return something;
29: 8b 45 fc mov eax,DWORD PTR [ebp-0x4]
2c: eb 05 jmp 33 <main+0x1e>
}else{
return 0;
2e: b8 00 00 00 00 mov eax,0x0
}
<强> CASE2 强>
if(something){
23: 83 7d fc 00 cmp DWORD PTR [ebp-0x4],0x0
27: 74 05 je 2e <main+0x19>
return something;
29: 8b 45 fc mov eax,DWORD PTR [ebp-0x4]
2c: eb 05 jmp 33 <main+0x1e>
return 0;
2e: b8 00 00 00 00 mov eax,0x0
您可以想象 没有差异 !
答案 1 :(得分:2)
如果输入`return,它将无法编译 认为一旦代码被编译,所有ifs,elses和循环都被改为goto的
If (cond) { code A } code B
转向
if cond is false jump to code b
code A
code B
和 如果(cond){code A} else {code B} code C
转向
if cond is false jump to code B
code A
ALWAYS jump to code C
code B
code C
大多数处理器在检查它们是否实际跳跃之前“猜测”它们是否会跳跃。根据处理器的不同,它可能会影响性能,从而无法猜测。
所以答案是肯定的! (除非在第一次比较结束时总是跳跃)进行ALWAYS跳跃需要2-3个周期,而不是在第一个if中。