以下哪项会更快执行?

Sac*_*tre 0 c c++ if-statement

可能重复:
"if,if,if"或"if,else if else else,else"

1.

if(flag == 1)
{
    .....
}
else if(flag == 2)
{ 
     .....
}
else if(flag == 3) // true condition
{
     .....
}
Run Code Online (Sandbox Code Playgroud)


2.

if(flag == 1)
{
    .....
}
if(flag == 2)
{ 
     .....
}
if(flag == 3) // true condition
{
     .....
}
Run Code Online (Sandbox Code Playgroud)

如果要执行最后一次if.

Hau*_*eth 6

我的测试显示第二个版本比前一个版本短4个指令,但优化版本长度相同:

我测试
代码:

main(a) {
  if(a == 10)
    puts("10");
  else if(a == 20)
    puts("20");
  else if(a < 100)
    puts("yes");
}
Run Code Online (Sandbox Code Playgroud)

Disassm:

   0x00000000004004dc <+0>: push   rbp
   0x00000000004004dd <+1>: mov    rbp,rsp
   0x00000000004004e0 <+4>: sub    rsp,0x10
   0x00000000004004e4 <+8>: mov    DWORD PTR [rbp-0x4],edi
   0x00000000004004e7 <+11>:    cmp    DWORD PTR [rbp-0x4],0xa
   0x00000000004004eb <+15>:    jne    0x4004f9 <main+29>
   0x00000000004004ed <+17>:    mov    edi,0x4005c4
   0x00000000004004f2 <+22>:    call   0x4003b0 <puts@plt>
   0x00000000004004f7 <+27>:    jmp    0x40051b <main+63>
   0x00000000004004f9 <+29>:    cmp    DWORD PTR [rbp-0x4],0x14
   0x00000000004004fd <+33>:    jne    0x40050b <main+47>
   0x00000000004004ff <+35>:    mov    edi,0x4005c7
   0x0000000000400504 <+40>:    call   0x4003b0 <puts@plt>
   0x0000000000400509 <+45>:    jmp    0x40051b <main+63>
   0x000000000040050b <+47>:    cmp    DWORD PTR [rbp-0x4],0x63
   0x000000000040050f <+51>:    jg     0x40051b <main+63>
   0x0000000000400511 <+53>:    mov    edi,0x4005ca
   0x0000000000400516 <+58>:    call   0x4003b0 <puts@plt>
   0x000000000040051b <+63>:    leave  
   0x000000000040051c <+64>:    ret    
Run Code Online (Sandbox Code Playgroud)

优化:

   0x00000000004004dc <+0>: sub    rsp,0x8
   0x00000000004004e0 <+4>: cmp    edi,0xa
   0x00000000004004e3 <+7>: jne    0x4004f1 <main+21>
   0x00000000004004e5 <+9>: mov    edi,0x4005c4
   0x00000000004004ea <+14>:    call   0x4003b0 <puts@plt>
   0x00000000004004ef <+19>:    jmp    0x400511 <main+53>
   0x00000000004004f1 <+21>:    cmp    edi,0x14
   0x00000000004004f4 <+24>:    jne    0x400502 <main+38>
   0x00000000004004f6 <+26>:    mov    edi,0x4005c7
   0x00000000004004fb <+31>:    call   0x4003b0 <puts@plt>
   0x0000000000400500 <+36>:    jmp    0x400511 <main+53>
   0x0000000000400502 <+38>:    cmp    edi,0x63
   0x0000000000400505 <+41>:    jg     0x400511 <main+53>
   0x0000000000400507 <+43>:    mov    edi,0x4005ca
   0x000000000040050c <+48>:    call   0x4003b0 <puts@plt>
   0x0000000000400511 <+53>:    add    rsp,0x8
   0x0000000000400515 <+57>:    ret   
Run Code Online (Sandbox Code Playgroud)

II测试
代码:

main(a) {
  if(a == 10)
    puts("10");
  if(a == 20)
    puts("20");
  if(a < 100)
    puts("yes");
}
Run Code Online (Sandbox Code Playgroud)

Disassm:

   0x00000000004004dc <+0>: push   rbp
   0x00000000004004dd <+1>: mov    rbp,rsp
   0x00000000004004e0 <+4>: sub    rsp,0x10
   0x00000000004004e4 <+8>: mov    DWORD PTR [rbp-0x4],edi
   0x00000000004004e7 <+11>:    cmp    DWORD PTR [rbp-0x4],0xa
   0x00000000004004eb <+15>:    jne    0x4004f7 <main+27>
   0x00000000004004ed <+17>:    mov    edi,0x4005c4
   0x00000000004004f2 <+22>:    call   0x4003b0 <puts@plt>
   0x00000000004004f7 <+27>:    cmp    DWORD PTR [rbp-0x4],0x14
   0x00000000004004fb <+31>:    jne    0x400507 <main+43>
   0x00000000004004fd <+33>:    mov    edi,0x4005c7
   0x0000000000400502 <+38>:    call   0x4003b0 <puts@plt>
   0x0000000000400507 <+43>:    cmp    DWORD PTR [rbp-0x4],0x63
   0x000000000040050b <+47>:    jg     0x400517 <main+59>
   0x000000000040050d <+49>:    mov    edi,0x4005ca
   0x0000000000400512 <+54>:    call   0x4003b0 <puts@plt>
   0x0000000000400517 <+59>:    leave  
   0x0000000000400518 <+60>:    ret
Run Code Online (Sandbox Code Playgroud)

优化:

   0x00000000004004dc <+0>: sub    rsp,0x8
   0x00000000004004e0 <+4>: cmp    edi,0xa
   0x00000000004004e3 <+7>: jne    0x4004f1 <main+21>
   0x00000000004004e5 <+9>: mov    edi,0x4005c4
   0x00000000004004ea <+14>:    call   0x4003b0 <puts@plt>
   0x00000000004004ef <+19>:    jmp    0x400507 <main+43>
   0x00000000004004f1 <+21>:    cmp    edi,0x14
   0x00000000004004f4 <+24>:    jne    0x400502 <main+38>
   0x00000000004004f6 <+26>:    mov    edi,0x4005c7
   0x00000000004004fb <+31>:    call   0x4003b0 <puts@plt>
   0x0000000000400500 <+36>:    jmp    0x400507 <main+43>
   0x0000000000400502 <+38>:    cmp    edi,0x63
   0x0000000000400505 <+41>:    jg     0x400511 <main+53>
   0x0000000000400507 <+43>:    mov    edi,0x4005ca
   0x000000000040050c <+48>:    call   0x4003b0 <puts@plt>
   0x0000000000400511 <+53>:    add    rsp,0x8
   0x0000000000400515 <+57>:    ret 
Run Code Online (Sandbox Code Playgroud)

Booth测试由Linux 3.2.14-1-ARCH x86_64 Intel(R)Core(TM)i5 CPU M 480 @ 2.67GHz上的gcc版本4.7.0 20120324(预发布)(GCC)编译.

编辑:正如@Als建议我将给出基本优化版本(-OGCC中的标志).

  • :+1,绝对棒极了. (2认同)

Alo*_*ave 5

它们在逻辑上不相同.一旦找到匹配条件,
首先不会检查其他if条件.无论先前的匹配如何,
第二次检查每个if条件.

如果你在第二种情况下使用块return内的语句if,那么它们在逻辑上是等价的.我相信同样高效.
但是,您需要在您的环境中对它们进行分析以确定.