使用goto跳过if语句会更快吗?

时间:2017-01-18 00:39:53

标签: c

如果语句为真,跳过if语句会更快吗?例如:

if (a = true) {
  blah blah...
  goto end;
} else {
  blah blah..
}

label: end;

此代码是否会快于:

if (a = true) {
  blah blah...
} else {
  blah blah..
}

2 个答案:

答案 0 :(得分:6)

如果任何体面的编译器没有为这两种可能性发出相同的汇编程序,我会感到惊讶。这是一个编译和运行的简单C程序:

web.config

使用#include <stdio.h> int main(void) { int c = getchar(); if (c == 'y') { ++c; goto end; } else { --c; } end: putchar(c); putchar('\n'); return 0; } 编译,没有优化标志,这里是输出:

gcc -S

编译器为删除了 .file "goto_skip_41709548.c" .text .globl main .type main, @function main: .LFB0: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 subq $16, %rsp call getchar movl %eax, -4(%rbp) cmpl $121, -4(%rbp) jne .L2 addl $1, -4(%rbp) jmp .L3 .L2: subl $1, -4(%rbp) .L3: movl -4(%rbp), %eax movl %eax, %edi call putchar movl $10, %edi call putchar movl $0, %eax leave .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE0: .size main, .-main .ident "GCC: (Ubuntu 4.9.4-2ubuntu1~14.04.1) 4.9.4" .section .note.GNU-stack,"",@progbits 的相同代码提供了完全相同的输出。已通过goto验证:

diff

答案 1 :(得分:5)

当您的代码编译时,它可能(即在大多数不错的编译器上)转换为类似于以下伪代码的内容:

    if (a != true)
        jump else

    foo() * will not execute if a is false 
          * because of the `jump else`
    jump end

else:
    bar() * will not execute if a is true 
          * because of the `jump end`

end:

其中elseend是标签(尝试在纸上使用true和false a运行它。)

基本上,两个代码段都会转换为相同的编译版本,而goto对结果的无影响,因为它包含在分支中。最多,它会使你的编译器再次出汗2毫秒来检测并忽略它。

在考虑性能时,半牵连的手动跳跃没有多大意义。打破循环,非重新声明和其他程序员端优化活动贡献更多。

作为一个注释,这个分支是如何构建汇编条件,因为将逻辑操作存储在寄存器中并进行比较以检查是否跳转。更精确的伪代码是

    cmp a, true /or/ xor a, a   ; 0 if true, 1 if false
    jne else    /or/ jnz else   ; jump if not equal / zero
    foo()
    jmp end    ; jump to
else:
    bar()
end: