2013-10-04 4 views
7

どの方法が高速でオーバーヘッドが少ないのか?ベクトルをクリアするか新しいベクトルを定義する方が速い。

方法1:

void foo() { 
    std::vector<int> aVector; 
    for (int i = 0; i < 1000000; ++i) { 
    aVector.clear(); 
    aVector.push_back(i); 
    } 
} 

方法2:

void foo() { 
    for (int i = 0; i < 1000000; ++i) { 
    std::vector<int> aVector; 
    aVector.push_back(i); 
    } 
} 

あなたは例が無意味であることを言うかもしれません!しかし、これは私の大きなコードからのちょっとした抜粋です。要するに私が知りたいことは

UPDATE

「をするたびに新しいベクトルを作成する」「一度ベクトルを作成し、使用するためにそれをクリアする」

または

に優れています

提案していただきありがとうございます。私は両方をテストしましたが、結果は

です。方法1:

$ time ./test1 

real 0m0.044s 
user 0m0.042s 
sys  0m0.002s 

方法2:ベクトルをクリア

$ time ./test2 

real 0m0.601s 
user 0m0.599s 
sys  0m0.002s 

が優れています。たぶんこれは他の誰かを助けるかもしれません。

+1

"ベクターをクリアするか、新しいベクターを定義する(どちらが速いのか)" - ベンチマークで知ることができます。プラットフォームや実装固有の詳細に非常に依存するため、一般的な記述はありません。 –

+0

申し訳ありませんが、g ++がメソッドの最適化コードをどのように生成するかを知りたいと思います。どちらがコンパイラに適していますか? – mahmood

+2

違いがあれば、 'clear'メソッドが高速になると思います。 –

答えて

6

は、以前のpush_back()秒間に割り振られたメモリを保持し、割り当ての必要性を減らすため、最も高速になる可能性が最も高いです。

ループごとに1つのコンストラクタコールと1つのデストラクタコールを削除します。

これは、コンパイラオプティマイザがこのコードで行う可能性のあることをすべて無視しています。

+0

+1私が書こうとしていたこと。 –

0

空のベクトルを作成することは、ほとんどオーバーヘッドではありません。ベクトルを大きなサイズに成長させるには、毎回サイズが倍増するため、非常に高価になる可能性があります。そのため、1Mのエントリベクトルには現在のコンテンツからなる15-20の「コピー」があります。

intのような単純な基本型の場合、オブジェクトを作成してオブジェクトを破棄するオーバーヘッドは「無」ですが、それ以上の複雑なオブジェクトの場合は、オブジェクトの構築と破棄、それはしばしば「オブジェクトをベクトルに入れる」および「ベクトルからオブジェクトを取り除く」よりも実質的に多い。つまり、各オブジェクトのコンストラクタとデストラクタは重要です。

EVERYでは「XまたはYの方が速い」ということは、理解したい状況のベンチマークが必要なことです。明らかに、「線形検索またはバイナリ検索」 of X elements "、ここで線形探索はXに比例し、二分探索はlog2(x)である)。

さらに、私はあなたの例について少し混乱しています.1つの要素をベクトルに格納することはかなり面倒であり、int x = i;以上のオーバーヘッドのオーバーヘッドがあります。ベンチマークではありません。言い換えれば、あなたの特定の比較は非常に公正ではありません。なぜなら、1Mベクターを明確に構築することは、1つのベクターを構築し、それを満たして1M回クリアすることよりも多くの仕事です。あなたのテストのようなもの作られた場合は、:

void foo() { 
    for (int i = 0; i < 1000; ++i) { 
    std::vector<int> aVector; 
    for(j = 0; j < 1000; j++) 
    { 
     aVector.push_back(i); 
    } 
    } 
} 

[および他のコードに対応する変更]を、私は結果がかなり類似して期待しています。

+0

std :: vectorはメモリを動的に割り当てます。動的割り当てルーチンが(この例のように)非常に頻繁に呼び出されると、データにコンストラクタがない場合でも大きなボトルネックになります。 clear()は通常内部データを縮小しないので、clearを呼び出す方が速くなります。 – SigTerm

+0

@SigTerm:そうですが、 'aVector.resize(1000)'を使って割り当てを避けることもできます。しかし、私が言ったように、それはベクトルに格納されているものに依存します。 –

+0

目的が 'push_back'要素であるなら、' aVector.reserve(1000) 'がより正確になります。 –

関連する問題