iterator
ちょっと気になって実験したのでその結果を。
本当はもっとしっかり調べて考察するべきでしょうが、ただ単に捨てるのが勿体無かったからなのが主な理由なのでちゃんと調べてません。
for(iterator it = v.begin(), stop = v.end() ; it != stop ; ++it)
forループ内でコンテナの要素に対して変更を行わない場合、forループで上記のように書けばv.end()の呼び出しが1回で済み高速になる・・・とどこかで見た気がしてずっとそうだと信じ込んでたのですが、それが本当か改めて調べてみました。
使用したコードは以下のコードです。
#include <iostream> #include <vector> #include <set> #include <windows.h> using namespace std; // ↓コメントインでstd::vectorを、コメントアウトでstd::setを使用します #define CONT_VECTOR // ↓コンテナに入れる要素の大きさ const int NUM = 10000000; #ifdef CONT_VECTOR typedef vector<int> CONTAINER; # define pb push_back #else typedef set<int> CONTAINER; # define pb insert #endif int main() { CONTAINER v; #ifdef CONT_VECTOR v.reserve( NUM ); #endif for( int i = 0 ; i < NUM ; ++i ) v.pb( i ); DWORD start, end; int sum; timeBeginPeriod(1); sum = 0; start = timeGetTime(); for( CONTAINER::iterator it = v.begin() ; it != v.end() ; ++it ) for( int i = 0 ; i < *it ; ++i ) sum += *it; end = timeGetTime(); cout << sum << ", iterator it != v.end(): " << (end - start) << endl; sum = 0; start = timeGetTime(); for( CONTAINER::iterator it = v.begin(), stop = v.end() ; it != stop ; ++it ) for( int i = 0 ; i < *it ; ++i ) sum += *it; end = timeGetTime(); cout << sum << ", iterator it != stop: " << (end - start) << endl; sum = 0; start = timeGetTime(); for( CONTAINER::const_iterator it = v.begin() ; it != v.end() ; ++it ) for( int i = 0 ; i < *it ; ++i ) sum += *it; end = timeGetTime(); cout << sum << ", const_iterator it != v.end(): " << (end - start) << endl; sum = 0; start = timeGetTime(); for( CONTAINER::const_iterator it = v.begin(), stop = v.end() ; it != stop ; ++it ) for( int i = 0 ; i < *it ; ++i ) sum += *it; end = timeGetTime(); cout << sum << ", const_iterator it != stop: " << (end - start) << endl; timeEndPeriod(1); return 0; }
Windows用です。
コンパイル時にはwinmm.libのリンクを忘れずに。
結果としてはどれも変わりませんでした。
まともに調べてないので具体的な数字は書きませんが、速い結果が出たと思ってももう一回実行すると遅くなったりで、平均すると結果は全部同じでした。
v.end()の呼び出し回数を減らしても最適化でその差は消えちゃうのかなぁ〜