如果你有一个布尔b
和一个int i
,那两个例子中哪一个更好?
int x = i-1;
if(!b)x--;
或
int x;
if(b)x = i-1;else x = i-2;
在两个示例中,b
为真x
为i-1
,否则x
为i-2
。您应该将x
声明为i-1
并在b
为假时递减,还是应该使用第二个示例?
答案 0 :(得分:10)
如果编译器没有将两个版本优化到相同的最佳装配,我会感到惊讶。除非您可以使用分析器证明它们具有重要意义,否则不要浪费您的时间进行微观优化。
回答你的问题:这是无关紧要的。这是gcc.godbolt.org与-Ofast
的“生成的汇编”比较。
volatile int state0;
volatile void f0(volatile int i, volatile bool b)
{
int x;
if(b)x = i-1;else x = i-2;
state0 = x;
}
...汇编为......
f0(int, bool): # @f0(int, bool)
mov dword ptr [rsp - 4], edi
mov byte ptr [rsp - 5], sil
movzx eax, byte ptr [rsp - 5]
or eax, -2
add eax, dword ptr [rsp - 4]
mov dword ptr [rip + state0], eax
ret
volatile int state1;
volatile void f1(volatile int i, volatile bool b)
{
int x = i-1;
if(!b)x--;
state1 = x;
}
...汇编为......
f1(int, bool): # @f1(int, bool)
mov dword ptr [rsp - 4], edi
mov byte ptr [rsp - 5], sil
mov eax, dword ptr [rsp - 4]
movzx ecx, byte ptr [rsp - 5]
or ecx, -2
add ecx, eax
mov dword ptr [rip + state1], ecx
ret
正如您所看到的,差异很小,如果允许编译器通过删除volatile
来更积极地进行优化,则极有可能消失。
以下是图片形式的类似比较,使用-Ofast -march=native -ffast-math
:
答案 1 :(得分:5)
检查汇编代码,因为优化器会优化,可能是同一解决方案的解决方案。
我可能会将其实现为:
int x = (b) ? i - 1 : i - 2;
为了便于阅读,优化程序很可能会将其视为您的第二个解决方案。