如果语句为真,跳过if
语句会更快吗?例如:
if (a = true) {
blah blah...
goto end;
} else {
blah blah..
}
label: end;
此代码是否会快于:
if (a = true) {
blah blah...
} else {
blah blah..
}
答案 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:
其中else
和end
是标签(尝试在纸上使用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: