-2

私は今日、古いコードの一部を最適化して読みやすくするために書き直していました (一部のコードにはかなり手抜きな注釈が付けられていたため)。

if( cond1 )
{
     // Do something.
}
else if( cond2 )
{
     // Do something else.
}

と:

if( cond1 )
{
     // Do something.
}
else 
{
     if( cond2 )
     {
          // Do something else.
     }
}

同じ数の比較が行われるはずなので、パフォーマンス コストは発生しないはずだと自分自身に言い聞かせましたが、見落としているものがあるかどうかだけ知りたかったのです。

4

4 に答える 4

8

それでは、実際のコンパイラを使用して違いがあるかどうか見てみましょう。

次のコード:

int foo(int a, int b)
{
  if(a)
    return 5;
  else if(b)
    return 2;
  else
    return 56582201;
}

int bar(int a, int b)
{
  if(a)
    return 5;
  else
  {
    if(b)
      return 2;
    else
      return 56582201;
  }
}

GCC 4.8.0 でコンパイルすると、g++ a.cpp -fdump-tree-gimple -c(そうです、最適化なしで) として呼び出され、次の GIMPLE (GCC の内部表現) が得られます。

int foo(int, int) (int a, int b)
{
  int D.2205;

  if (a != 0) goto <D.2203>; else goto <D.2204>;
  <D.2203>:
  D.2205 = 5;
  return D.2205;
  <D.2204>:
  if (b != 0) goto <D.2206>; else goto <D.2207>;
  <D.2206>:
  D.2205 = 2;
  return D.2205;
  <D.2207>:
  D.2205 = 56582201;
  return D.2205;
}


int bar(int, int) (int a, int b)
{
  int D.2211;

  if (a != 0) goto <D.2209>; else goto <D.2210>;
  <D.2209>:
  D.2211 = 5;
  return D.2211;
  <D.2210>:
  if (b != 0) goto <D.2212>; else goto <D.2213>;
  <D.2212>:
  D.2211 = 2;
  return D.2211;
  <D.2213>:
  D.2211 = 56582201;
  return D.2211;
}

ご覧のとおり、違いは変数名とラベル名のみであり、これらは後で破棄されます。

Clang でコンパイルすると、同様の結果が得られます。LLVM IR は実質的に同じです。

いいえ、最適化なしでコンパイルしても違いはありません。

于 2013-05-07T14:22:19.670 に答える
7

それらはまったく同じです。コンパイラは、記述したとおりにコードをコンパイルしません。何かを書いた方法に違いがあるからといって、コンパイルされた実行可能ファイルに違いがあるわけではありません。結果のプログラムが C++ 標準の記述どおりに動作する限り、好きなだけ操作することができます。これは as-if ルールとして知られています。あなたが提供した 2 つのコード サンプルは、標準に従ってまったく同じ動作をするため、コンパイラはそれらを同じ実行可能ファイルにコンパイルする可能性があります。

于 2013-05-07T14:16:11.650 に答える
2

いいえ、細断ではありません。コンパイラがこれらに対して異なるコードを生成するかどうかは疑わしいです。

于 2013-05-07T14:15:40.540 に答える
2

言語に関する限り、これら 2 つの構造は同一です。生成されるコードも同一である必要があります。

于 2013-05-07T14:15:53.070 に答える