int y = 17*x;
int y = x + 16*x;
int y = x + (x<<4)
すべてが数値的に 17x に等しいですが、実行などの点でそれらの間に違いはありますか?
int y = 17*x;
int y = x + 16*x;
int y = x + (x<<4)
すべてが数値的に 17x に等しいですが、実行などの点でそれらの間に違いはありますか?
1) int y = 17*x;
2) int y = x + 16*x;
3) int y = x + (x<<4);
違いは次のとおりです。1) 読み取り可能、2) あいまい、3) さらにあいまいです。
最新のコンパイラでは、乗算をビット単位の命令に置き換える手動の最適化は必要ありません。ほとんどの場合、3 つの選択肢すべてが同じマシン コードに変換されます。
コンパイラが悪く、同じ機械語コードに変換されない場合、特定の CPU アーキテクチャに対する基礎となるアセンブラ命令の速度に依存するため、どれが最速かを知ることはできません。従来、論理シフト命令は乗算命令よりも高速ですが、これがすべての CPU に当てはまるとは限りません。
厳密には、 の型と値に依存しますx
。符号付きのオーバーフローはint
、標準に関する限り未定義の動作であるため、たとえば、コードにオーバーフローする操作が 2 つ含まれているか、1 つだけ含まれているかによって、実装の動作が異なる場合があります。
すべてが範囲内にある整数であると仮定すると、ステートメントは同じ意味を持ちます。それらはすべてまったく同じ出力コードになる可能性がありますが、コンパイラとコンパイラ オプションで確認する必要があります。これは、最適化が進んでいるほど可能性が高くなります。
また、最初のコードに対して 1 つのバージョンのコードが発行され (コンパイラーが乗算を発行)、他の 2 つのコードに対して別のコードが発行される (コンパイラーが加算と 16 による乗算または 4 によるシフトのいずれかを発行する) ことも考えられます。 )。最適化がなくても、コンパイラは1<<4
コンパイル時に評価します。標準では、コンパイラがそのような式をいくつかのコンテキストで評価できる必要があるため、コンパイラがそうしない理由はありません。