0

ループのすべての反復で同じであるforループにメソッド呼び出しがある場合、コンパイラはそれを最適化するのに十分賢いですか?

 for (int j = 0; j < 24; j++ ) {
        *destinationPointer++ = identityArray[j] * (1 / powf(2, valueFromAboveInMethod));
 }     

または、明示的にループの前の値に割り当てる必要がありますか?

 float value = 1 / powf(2, valueFromAboveInMethod);

 // populate the array
 for (int j = 0; j < 24; j++ ) {
        *destinationPointer++ = identityArray[j] * value;
 }     

コンパイラがここで素晴らしいことをして、floatに4バイトを使用する必要がなかったら、私はもっと幸せになるでしょう-これは再帰的なメソッドの中にあります。

4

3 に答える 3

2

個人的には、ここで変数を使用します。より良いコードを提供する可能性があるだけでなく、値が変更されないことをコードを読んでいる人に示すためでもあります [ただし、「値」よりも適切な変数名を付けます]。コンパイラーが実際に値を事前に計算することを期待していますが、前述のように、それは純粋な関数であるというコンパイラーの理解に依存していpowfます (副作用がなく、毎回同じ入力に対して同じ結果が得られます)。

再帰呼び出しで余分な変数を使用した結果としての追加のストレージは、「まあ、それは問題ではない」か、「スタックオーバーフローの深淵の端に非常に近い」場合のいずれかです。スタック オーバーフローはおそらく最悪のタイプのクラッシュの 1 つです。これは、プログラムが回復するためにスタックを使用する必要があり、オーバーフローした利用可能な唯一のスタックである可能性があるため、警告も回復方法もまったく提供しないためです。再帰関数が制限されていないか、再帰呼び出しの数がスタックの制限内にあることを保証できない場合は、この関数を再設計することをお勧めします。深い再帰は、多くの場合非常に非効率的です。

-- マット

于 2013-03-20T20:07:54.413 に答える
1

どのオプションを使用してコンパイルするかによって異なります。通常、最小限の最適化を有効にしたコンパイラでも、このような単純な最適化を処理しますが、2 番目のコードで記述したように、自分で行う方がよいでしょう。とにかく、コンパイラがそれを最適化する場合、additional 4 bytes値はどこにでも保存する必要があるため、それも維持されます。

于 2013-03-20T19:48:40.030 に答える
0

コンパイラは、powf がステートレスであることを認識できるほど賢くない可能性があります。

疑わしい場合は、アセンブラにコンパイルして自分で確認してください。

于 2013-03-20T19:58:51.043 に答える