2009-08-27 4 views
3

私は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秒を報告します。

+2

forループとwhileループの順番を逆にしてみてください。 – obelix

+0

それは素晴らしい提案です。最初のテストで必要なデータをキャッシュに取り込むと、そのデータに2回目にアクセスしたときにパフォーマンスが大幅に向上します。その効果を中和する別の方法は、テストを2つの別々のプロセスとしてコーディングすることです。 –

+0

最適化でコンパイルしていますか? Visual Studioでこれをやっているのであれば、Microsoftの最新イテレータチェック機能をオフにしてコンパイルしていますか? – luke

答えて

11
if(*p = val) return p; 

これは==である必要があります。したがって、forfindは最初の値0のベクトル全体を調べ、直ちに番号1〜9999に戻ります。

+0

あなたはそれを持っている!しかし、forループはまだ短い時間を出力します。 – trikker

+0

ああ、あなたは速く、担当者を集めてください:) –

+3

@trikker:コンパイラの最適化をオンにします。たとえば、gcc v4.3.2では、-O2レベルは/ 0.04/0.06の間に生成され、-O0レベルは.72/.66を生成します。 10倍高速に動作するだけでなく、C++を使用するあらゆる場所で-O2を使用しますが、_while_ easillyは_for_ループよりも優れています。 –

関連する問題