vector::length() のようなメソッドを数回呼び出すコードがあるとします...次のような一時変数を作成します
int length=myVector.length()
メソッドを数回呼び出すよりも効率的ですか?
これはやや仮説的な質問なので、 vector::length() を呼び出すことが目的の結果を得る唯一の方法であると仮定しましょう。
ローカル変数に値を格納するコストはほとんどありません。インライン化された「このメンバー変数を取得する」を呼び出すコストも、ほとんどありません。
一方、オブジェクトがベクトルでlength
はなく、メンバー変数に保持されていないが、カウントする必要がある場合 (たとえば のようstrlen()
に)、それをローカル変数に格納することには大きな利点があります。特に文字列の長さが数文字を超える場合。
他の問題はもちろん、次のようなことをすることです:
int number_of_widgets = my_widgets.length();
... // more code here, but none that affect my_widgets.
last_widget = my_widgets[number_of_widgets-1];
...
そして、他の誰かが行って、cdoe を編集します。
int number_of_widgets = my_widgets.length();
... some code.
my_widgets.erase(some_widget_iterator);
... // more code here
last_widget = my_widgets[number_of_widgets-1];
...
コードが有効な範囲外にアクセスしているため、クラッシュして燃える可能性があります...
いつものように、悪魔は細部に宿ります。あなたのコードで最速のものを知りたい場合は、コードを使用してベンチマークしてください...
この場合、速度について心配する必要はありません。直接 length() を呼び出す方が高速です。読みやすくするために、本当に何度も呼び出さない限り、直接呼び出してください。10 行で 10 回呼び出されるなど、コードが醜くなる場合は、変数にキャッシュしてコードの見栄えを良くすることができます。
最適化のルール 1: 最適化しない。とにかく速いです。vector::length() がプログラムの速度を低下させるとは思いませんが、速度の問題がない限り、手動で最適化する正当な理由はありません。スマート コンパイラは、関連する場合はそれを決定して最適化する必要があります。
IDE ではコード補完機能があるため、これ以上入力することは問題ではなく、コードの視覚的な読みやすさだけです (繰り返しますが、この特定の機能がプログラムの速度を低下させているとは思えません)。
確実に判断する唯一の方法は、コードをプロファイリングすることです。
個人的には、ベクトルが現在のスコープで変更されないことがわかっている場合は、最初に読みやすさを最適化し、必要に応じてプロファイリング に基づいて調整を行います。
const int number_of_widgets = myVector.size();
「わずかな効率については忘れるべきです。たとえば、約 97% の確率で: 時期尚早の最適化は諸悪の根源です」 -- ドナルド・クヌース
本当の答えは、可能であればイテレータを使用する必要があるということです。イテレータの方が一般的に高速であり、この問題を完全に回避できるからです (ベクトルが再割り当てされないと仮定します)。
おそらく探している答えは次のとおりです。通常、単純なケースでは最適化されますが、常にではありません。
どちらも同じコードにコンパイルされると思います。しかし、仮定はダメなので、テストプログラムを試してみました。私は最初にコンパイルしました:
#include <iostream>
#include <vector>
int main()
{
int myints[] = {16,2,77,29};
std::vector<int> myVector (myints, myints + sizeof(myints) / sizeof(int) );
int length=myVector.size();
std::cout << length << std::endl;
std::cout << length*3 << std::endl;
return 0;
}
これにより、4 と 12 の出力が正しく得られます。次に、変数「長さ」を使用しないこのプログラムを試しました。
#include <iostream>
#include <vector>
int main()
{
int myints[] = {16,2,77,29};
std::vector<int> myVector (myints, myints + sizeof(myints) / sizeof(int) );
std::cout << myVector.size() << std::endl;
std::cout << myVector.size()*3 << std::endl;
return 0;
}
このプログラムは、4 と 12 を正しく出力し、まったく同じことを行いましたが、その間に可変長はありませんでした。コンパイル フラグ -O3 または -O2 を使用すると、まったく同じバイナリ コードが得られると言えます。これは gcc コンパイラで行われました。したがって、どちらの方法も高速ではなく、どちらも同じ量のメモリを使用します。
したがって、見栄えがよく、読みやすい方を使用してください。
他の最適化が行われている可能性があるため、私のテストから完全に一般化できるかどうかはわかりませんが. たとえば、コンパイル時に myVector.size() がこの時点で 4 と計算された可能性があるため、実行時に計算されるのではなく、ファイルにハードコーディングされている可能性があります。これにより、私のテストはかなり無意味になります。
お役に立てれば。(これを書いている間に他の4つの回答が書かれていることがわかりますが)、他の誰かがおそらくこれをテストするより良い仕事をしているでしょう。