考虑以下
while(true)
{
if(x>5)
// Run function A
else
// Run function B
}
如果 x 总是小于 5,Visual Studio 编译器会做任何优化吗?即,从不检查 x 是否大于 5 并始终运行函数 B
考虑以下
while(true)
{
if(x>5)
// Run function A
else
// Run function B
}
如果 x 总是小于 5,Visual Studio 编译器会做任何优化吗?即,从不检查 x 是否大于 5 并始终运行函数 B
这取决于编译器是否“知道”x
总是小于5
.
是的,几乎所有现代编译器都能够删除分支。但是编译器需要能够证明分支总是朝着一个方向发展。
下面是一个可以优化的例子:
int x = 1;
if (x > 5)
printf("Hello\n");
else
printf("World\n");
拆解是:
sub rsp, 40 ; 00000028H
lea rcx, OFFSET FLAT:??_C@_06DKJADKFF@World?6?$AA@
call QWORD PTR __imp_printf
x = 1
可证明小于5
。所以编译器能够删除分支。
但是在这个例子中,即使你总是输入小于 5,编译器也不知道。它必须承担任何输入。
int x;
cin >> x;
if (x > 5)
printf("Hello\n");
else
printf("World\n");
拆解是:
cmp DWORD PTR x$[rsp], 5
lea rcx, OFFSET FLAT:??_C@_06NJBIDDBG@Hello?6?$AA@
jg SHORT $LN5@main
lea rcx, OFFSET FLAT:??_C@_06DKJADKFF@World?6?$AA@
$LN5@main:
call QWORD PTR __imp_printf
树枝留着。但请注意,它实际上将函数调用提升到了分支之外。所以它真的把代码优化成这样:
const char *str = "Hello\n";
if (!(x > 5))
str = "World\n";
printf(str);