私はSTLアルゴリズムについて読んでいます。本書では、findのようなアルゴリズムはforループではなくwhileループを使用していることを指摘しています。私はいくつかのテストを行うことにしましたが、結果は実際には一致しませんでした。2つのループスタイルの速度比較
forfindは、一貫してwhilefindよりも優れています。最初に、10000のintをベクトルにプッシュしてから、findを使用して単一の値を取得し、イテレータに返してテストしました。私はそれを計時し、その時間を出力する。
次に、forfind関数とwhilefind関数が複数回(この場合は10000回)使用されるように変更することにしました。しかし、forループの発見は、whileの発見よりも優れたパフォーマンスを引き出しました。誰もこれを説明できますか?ここにコードがあります。
#include "std_lib_facilities.h"
#include<ctime>
template<class ln, class T>
ln whilefind(ln first, ln last, const T& val)
{
while (first!=last && *first!=val) ++first;
return first;
}
template<class ln, class T>
ln forfind(ln first, ln last, const T& val)
{
for (ln p = first; p!=last; ++p)
if(*p == val) return p;
return last;
}
int main()
{
vector<int> numbers;
vector<int>::iterator whiletest;
vector<int>::iterator fortest;
for (int n = 0; n < 10000; ++n)
numbers.push_back(n);
clock_t while1 = clock(); // start
for (int i = 0; i < 10000; ++i)
whiletest = whilefind(numbers.begin(), numbers.end(), i);
clock_t while2 = clock(); // stop
clock_t for1 = clock(); // start
for (int i = 0; i < 10000; ++i)
fortest = forfind(numbers.begin(), numbers.end(), i);
clock_t for2 = clock(); // stop
cout << "While loop: " << double(while2-while1)/CLOCKS_PER_SEC << " seconds.\n";
cout << "For loop: " << double(for2-for1)/CLOCKS_PER_SEC << " seconds.\n";
}
whileループは一貫して0.78秒、forループは0.67秒を報告します。
forループとwhileループの順番を逆にしてみてください。 – obelix
それは素晴らしい提案です。最初のテストで必要なデータをキャッシュに取り込むと、そのデータに2回目にアクセスしたときにパフォーマンスが大幅に向上します。その効果を中和する別の方法は、テストを2つの別々のプロセスとしてコーディングすることです。 –
最適化でコンパイルしていますか? Visual Studioでこれをやっているのであれば、Microsoftの最新イテレータチェック機能をオフにしてコンパイルしていますか? – luke