6

これが私が意味することです、私が次のようなコードを持っていると仮定します:

for (int i = 0; i < 1000; i++) {
    char* ptr = something;
    /*
    ... use ptr here
    */
}

char* ptrループ内で毎回割り当てられ、効果がないように見えますか?

これを書く方が効果的ですか?

char* ptr = something;
for (int i = 0; i < 1000; i++) {
    /*
    ... use ptr here
    */
}

この興味深い問題についてコメントしてください。ありがとうございました!

ありがとう、BodaCydo。

4

6 に答える 6

13

パフォーマンスに違いが生じる可能性がありますが、必要に応じて、多くの最適化コンパイラがこの最適化を実行します。これは「ループ不変コードモーション」と呼ばれます。

于 2010-07-28T13:30:45.530 に答える
2

私は、変数名の範囲を可能な限り制限する方がよいと考えている学校です。がループの外部で参照されることを意図していない場合ptrは、ループの外部で宣言しないでください。

ただし、somethingコストのかかる操作であり、不変であり(つまり、に依存しないi)、コードがハードパフォーマンス要件を満たすのを妨げている場合は、そうです。宣言をループの外に移動する必要があります

これは言葉では言い表せないほど醜いですが、次のようなことができます。

do
{
  char *ptr = something;
  for (int i = 0; i < 1000; i++)
  {
    /* use ptr here */
  }
} while (0);

まだスコープを制限してptrいますが、ループの反復ごとにスコープを割り当てる必要はありません。

于 2010-07-28T14:27:32.717 に答える
1

コードが変換される方法は、実際にはコンパイラとそれが実行する最適化によって異なります。コンパイラーは、「ダム」変換を実行してすべてのループを割り当てる場合があります。または、最適化フェーズでループの外側に割り当てを配置する場合があります。安全のために、宣言をループの外側に配置します。他の場合と同様に、両方をテストして、違いがあるかどうかを確認するために各ループにかかる時間を確認できます。

于 2010-07-28T13:30:17.217 に答える
0

'C'プログラムの個人的な慣習として、変数宣言を関数の先頭、ファイルの先頭、または共通の.hファイルに配置するのが好きです。コード内に宣言を埋め始めると、混乱を招きやすく、変数のスコープを見失いやすくなり、望ましくない結果が生じる可能性があります。

于 2010-07-28T13:34:14.787 に答える
0

例のような組み込みタイプのchar*場合、大きな違いはありません。2番目の形式は、ループが終了した後に使用でき、初期化子を1回だけ評価します。しかし、ジョンが言うように、ほとんどのコンパイラはとにかく初期化を事前に計算します。

ptrループ内で再割り当てされた場合(再割り当てしない場合は、再割り当てする必要がありますchar* const ptr)、値がリセットされずに前の反復から保持されるという点で、明らかな違いがあります。

最後に、非PODタイプでは、ループの反復ごとにコンストラクタとデストラクタが実行されます。

于 2010-07-28T13:34:32.640 に答える
0

プロファイルを作成して、自分の目で確かめる必要があります。参考として、私のこの質問(および受け入れられた回答)を確認してください。jalfが言うように、それが最適化されることを期待するのは経験則です(そして、おそらくPODタイプには正しいでしょう)、プロファイリングでバックアップする必要があります。

于 2010-07-28T13:32:26.040 に答える