1. ホーム
  2. c++

[解決済み] If文とif-else文、どちらが速いか?

2023-03-25 06:23:23

質問

先日、友人とこの2つのスニペットについて議論しました。どちらが速いのか、そしてそれはなぜなのか?

value = 5;
if (condition) {
    value = 6;
}

とする。

if (condition) {
    value = 6;
} else {
    value = 5;
}

もし value が行列の場合は?

注:私は value = condition ? 6 : 5; が存在することは知っていますし、その方が高速であることも期待していますが、選択肢には入っていませんでした。

Edit (質問が現在保留されているため、スタッフから依頼されました)。

  • 以下のいずれかを考慮して回答してください。 x86 アセンブリ 主流のコンパイラによって生成される ( g++、clang++、vc、mingw と言ってください。 ) の最適化バージョンと非最適化バージョンの両方、あるいは MIPS アセンブリ .
  • アセンブリが異なる場合、なぜそのバージョンが速いのか、また、どのような場合にそうなるのかを説明します ( 例: "分岐がなく、分岐には次の問題があるため、より優れている blahblah" )

どのように解決するのですか?

TL;DRです。 最適化されていないコードでは if がなく else は無関係に効率的に見えますが、最も基本的なレベルの最適化でさえ有効にすると、コードは基本的に次のように書き直されます。 value = condition + 5 .


I 試してみた を試してみたところ、以下のコードのアセンブリが生成されました。

int ifonly(bool condition, int value)
{
    value = 5;
    if (condition) {
        value = 6;
    }
    return value;
}

int ifelse(bool condition, int value)
{
    if (condition) {
        value = 6;
    } else {
        value = 5;
    }
    return value;
}

gcc 6.3 で最適化を無効にしている場合 ( -O0 ) の場合、関連する差分は

 mov     DWORD PTR [rbp-8], 5
 cmp     BYTE PTR [rbp-4], 0
 je      .L2
 mov     DWORD PTR [rbp-8], 6
.L2:
 mov     eax, DWORD PTR [rbp-8]

に対して ifonly が、一方 ifelse

 cmp     BYTE PTR [rbp-4], 0
 je      .L5
 mov     DWORD PTR [rbp-8], 6
 jmp     .L6
.L5:
 mov     DWORD PTR [rbp-8], 5
.L6:
 mov     eax, DWORD PTR [rbp-8]

後者は余分なジャンプがあるため若干効率が悪く見えますが、どちらも少なくとも2つ、多くても3つの割り当てがあるので、本当に最後の一滴まで性能を絞り出す必要がない限り(ヒント:スペースシャトルに取り組んでいない限り、そうではありませんし、そうであったとしても おそらく ヒント: スペース シャトルで作業していない限り、そのようなことはありませんし、その場合でも、おそらくありません)。

しかし、最も低い最適化レベルでも ( -O1 ) でも、両関数は同じになります。

test    dil, dil
setne   al
movzx   eax, al
add     eax, 5

とは基本的に同じです。

return 5 + condition;

仮定 condition が 0 か 1 であると仮定します。 より高い最適化レベルでは、出力はあまり変わりません。 movzx を効率的にゼロにすることで EAX レジスタを効率的にゼロにすることによって


免責事項です。 あなたはおそらく 5 + condition を自分で書くべきではありません(標準では true を整数型に変換すると 1 というのは、あなたのコードを読む人(将来の自分も含む)にとって、あなたの意図はすぐにはわからないかもしれないからです。) このコードのポイントは、コンパイラが両方のケースで生成するものが(実質的に)同じであることを示すことです。 Ciprian Tomoiaga はコメントで非常にうまくそれを述べています。

<ブロッククオート

a 人間 の仕事は、コードを書くことです。 人間のために であり コンパイラに のためのコードを書く。 マシン .