より効率的なものは何ですか?なんで?
オプション1:
int n = someFunction();
for (int i = 0; i < n ; i++)
//do something...
オプション 2:
for (int i = 0; i < (someFunction()); i++)
//do something...
返信ありがとうございます!
2 つのループは等価ではありません。someFunction()
複数回呼び出したときに が異なる値を返すと予想される場合、結果は異なります。
whensomeFunction()
が何回呼び出しても同じ値を返す場合、最初のオプションはsomeFunction()
よりも大きいか等しい数値を返す場合により効率的になります1
。を返す場合は0
、違いはありません。
タイミングの違いはsomeFunction()
、制限を取得するために 2 番目のオプションがループ内で繰り返し呼び出されるという事実によるものです。関数呼び出しが非常に高速であっても、このコードは最適ではありません
前者は常に少なくとも後者と同じくらい効率的です。前者では、評価someFunction
は 1 回だけです。後者では、すべての反復でそれを呼び出しています。
スマート コンパイラは、後者の場合の本体をインライン化し、someFunction
それが定数である可能性があることを認識して、実質的に等しくすることができますが、最初のものは決して遅くなりません。
時々、JavaScript から規則を借りて、次のようなことを行います。
for(size_t i = 0, l = someFunction(); i < l; i++) {
// ...
}
これは事実上、最初のバージョンと同じですが、2 番目のバージョンのように少し簡潔になっています。
オプション 1 では、最初の呼び出しで 0 より大きい値を返すSomeFunction()
一般的なケースで、呼び出しが少なくなります。someFunction()
したがって、より効率的になります。
オプション 2 は、コンパイラが の本体を確認でき、コードsomeFunction()
で何が起こっても常に同じ値を返すと判断できない限り、最適化できません。...do something...
最初のものは i を定数と比較して for ループ条件を評価するため効率的ですが、2 番目の for ループは繰り返しごとに someFunction() を評価します。
最初のものは、 someFunction を一度だけチェックするため、より効率的です。2番目のものでは、ループごとに someFunction() を何度もチェックします