ブール値b
と、i
がある場合、どちらの方が良いでしょうか?両方の例でブール値に基づいて値を決定する最速の方法+ +
int x = i-1;
if(!b)x--;
または
int x;
if(b)x = i-1;else x = i-2;
b
がtrueの場合x
はx
がi-2
ある他、i-1
です。 x
をi-1
と宣言し、b
が偽の場合、または2番目の例を使用する必要がある場合は、減らしてください。
ブール値b
と、i
がある場合、どちらの方が良いでしょうか?両方の例でブール値に基づいて値を決定する最速の方法+ +
int x = i-1;
if(!b)x--;
または
int x;
if(b)x = i-1;else x = i-2;
b
がtrueの場合x
はx
がi-2
ある他、i-1
です。 x
をi-1
と宣言し、b
が偽の場合、または2番目の例を使用する必要がある場合は、減らしてください。
コンパイラが両方のバージョンを同じ最適なアセンブリに最適化しなかった場合、私は驚くでしょう。プロファイラを使用して重要であることを証明できない限り、このマイクロ最適化で時間を無駄にしないでください。
あなたの質問に答えるには:それは無関係です。ここでは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;
}
... ... ...に
volatile int state1;
volatile void f1(volatile int i, volatile bool b)
{
int x = i-1;
if(!b)x--;
state1 = 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
をコンパイルさ
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
を使用して、画像の形で同様の比較です:
はあなたが使用しているフラグを明記してください(-03?) –
@IvanRubinson:それはgodboltリンク上で、私は '-Ofast'を使用します。 –
ありがとう!私が好奇心が強いからと言って、私は尋ねていた。 – theo2003
オプティマイザは同じソリューションに両方のあなたのソリューションおそらく、最適化するために、アセンブリコードを確認してください。
私はおそらくとしてそれを実装します:そうオプティマイザはあなたの第二の溶液として、それは同じようになります読みやすさと高いため
int x = (b) ? i - 1 : i - 2;
。
ブランチレス版は 'x = i - 2 + b; –
です。リリースでコンパイルした場合、コンパイラは同じコードを出力します – user
なぜ尋ねるのですか?マイクロ最適化は無関係です。 –