Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 以下哪项执行速度更快?_C++_C_If Statement - Fatal编程技术网

C++ 以下哪项执行速度更快?

C++ 以下哪项执行速度更快?,c++,c,if-statement,C++,C,If Statement,可能重复: 一, 或 二, 如果它最后一次执行,如果。同时执行;如果第一个If条件为true,则代码的第一个块将快速执行。它们在逻辑上并不等价。 First在找到匹配条件后不会检查其他if条件。 第二个检查每个if条件,而不考虑之前的任何匹配 如果在第二种情况下,在If块中使用return语句,那么它们在逻辑上是等价的。我相信它们的性能是相同的。 但是,您需要在您的环境中对它们进行概要分析以确保安全。从技术上讲,您提供的两个代码片段并不相同,因此比较它们没有意义 在第二个示例中可能会执行多个i

可能重复:

一,

或 二,


如果它最后一次执行,如果。

同时执行;如果第一个If条件为true,则代码的第一个块将快速执行。

它们在逻辑上并不等价。 First在找到匹配条件后不会检查其他if条件。 第二个检查每个if条件,而不考虑之前的任何匹配

如果在第二种情况下,在If块中使用return语句,那么它们在逻辑上是等价的。我相信它们的性能是相同的。
但是,您需要在您的环境中对它们进行概要分析以确保安全。

从技术上讲,您提供的两个代码片段并不相同,因此比较它们没有意义

在第二个示例中可能会执行多个if块,而第一个示例只保证执行通过该块的一条路径。因此,在这一点上,如果您假设平均有多个条件会成功,那么可以说第一个条件执行得更快

但是,如果您假设只有一条路径会执行,那么就不可能再确定地说,除非您知道编译器将如何将此代码转换为程序集,因为程序集没有条件基元ie if else


汇编语言使用比较、小于零时跳转和零时跳转等指令来实现条件逻辑。在不知道相关优化的情况下,编译器可能无法确定哪一个执行得更快。

从逻辑上讲,代码片段不是等价的,不是吗。比如,第一个说

if (a==0)
{
}
else if (a < 10)
{
}
else if (a > 10)
{
}
第二个是

if (a ==0)
{
}
if (a < 10)
{
}
if (a > 10)
{
}

以上是一个非常琐碎的例子。但是,如果您试图比较if语句的执行时间,假设它们在逻辑上是等价的,那么第一个语句会更快,因为永远不会执行else语句。在第二种情况下,将评估if条件,而不考虑早期的if语句。

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

我测试 代码:

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    
   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
优化:

   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   
   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 
II试验 代码:

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    
   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
优化:

   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   
   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 
展台测试由gcc版本4.7.0 20120324在Linux 3.2.14-1-ARCH x86_64 IntelR CoreTM i5 CPU M 480@2.67GHz上预发布的gcc编译


编辑:正如@Als建议的那样,我将在GCC中给出带有基本优化-O标志的版本。

只是为了添加到@Haulet的帖子中,这是我在使用优化编译时得到的:

jirka@debian:~/xpath/libxml-xpathengine-perl$ diff -Naur ./-.s o2.s 
--- ./-.s       2012-04-09 12:50:50.000000000 +0200
+++ o2.s        2012-04-09 12:52:25.000000000 +0200
@@ -22,43 +22,34 @@
        subl    $16, %esp
        movl    8(%ebp), %eax
        cmpl    $10, %eax
-       je      .L8
-       cmpl    $20, %eax
        je      .L9
+       cmpl    $20, %eax
+       je      .L10
        cmpl    $99, %eax
-       jle     .L10
+       jle     .L3
        leave
        .cfi_remember_state
        .cfi_restore 5
        .cfi_def_cfa 4, 4
        .p2align 4,,4
        ret
-.L10:
-       .cfi_restore_state
-       movl    $.LC2, (%esp)
-       call    puts
-       leave
-       .cfi_remember_state
-       .cfi_restore 5
-       .cfi_def_cfa 4, 4
-       ret
-.L8:
+.L9:
        .cfi_restore_state
        movl    $.LC0, (%esp)
        call    puts
+.L3:
+       movl    $.LC2, (%esp)
+       call    puts
        leave
        .cfi_remember_state
        .cfi_restore 5
        .cfi_def_cfa 4, 4
        ret
-.L9:
+.L10:
        .cfi_restore_state
        movl    $.LC1, (%esp)
        call    puts
-       leave
-       .cfi_restore 5
-       .cfi_def_cfa 4, 4
-       ret
+       jmp     .L3
        .cfi_endproc
 .LFE0:
        .size   main, .-main
正如您所看到的,标签已重新标记为L8->L9、L9->L10、L10->L3,但代码大体相同,只是功能上有所不同

我用

gcc-4.7 -S -O3 -march=k8 -x c - 

它们在逻辑上通常是不等价的,这取决于您的编译器、它如何优化事物,以及您的平台。唯一知道的方法是用你的特定数据集进行基准测试。我知道它们在逻辑上是不等价的。但假设条件的每个if语句中使用相同的变量。我对switch语句不感兴趣。我问这个问题只是为了自我完善,所以如果这个问题是在面试中提出的,我将能够回答我的其余评论:这要看情况而定。你需要用你期望的数据在你的平台上进行基准测试。这是一个不错的Qn,但可能是重复的。为什么要投反对票?因为Q是专门关于性能的,所以通过启用优化来运行测试是有意义的。如果启用优化,您可能会得到相同的汇编指令。我可以试试,但这将是一篇很长的文章。提问者可以自己做。当你有5张或更多的选票时,我会这样做:在这种情况下,这是一个误导性的答案,得到了我的-1。注意,优化打开后,我看不出有任何差异,装配是相同的,除了一些RET ar替换为jmp,由于第二个版本与第一个版本不同。删除了否决票。正如预期的那样,启用优化后没有区别。希望这能证明我最初对答案的评论具有误导性。