2017-12-26 7 views
1

の性能I同じの複数の実行のために様々なN.C++:STD対のstd ::ベクトル::リスト

void vectorPerf(size_t n) 
{ 
    std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now(); 
    std::vector<size_t> cache; 
    for (size_t i = 0; i < n; i++) { 
     cache.push_back(i); 
    } 
    std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now(); 

    auto duration = std::chrono::duration_cast<std::chrono::microseconds>(t2-t1).count(); 

    std::cout << duration << " us." << "\n"; 

    return; 
} 

void listPerf(size_t n) 
{ 
    std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now(); 
    std::list<size_t> cache; 
    for (size_t i = 0; i < n; i++) { 
     cache.push_back(i); 
    } 
    std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now(); 

    auto duration = std::chrono::duration_cast<std::chrono::microseconds>(t2-t1).count(); 

    std::cout << duration << " us." << "\n"; 

    return; 
} 

int main(int argc, char** argv) 
{ 

    if (argc != 2) { 
     return -1; 
    } 
    std::stringstream ss(argv[1]); 
    size_t n; 
    ss >> n; 
    vectorPerf(n); 
    std::cout << "\n"; 
    listPerf(n); 
    std::cout << "\n"; 
} 

のためのstd ::リスト対のstd ::ベクトル性能をプロファイリングするために、次のコードを持っています

N  std::vector std::list 
1000 46   116 
2000 85   217 
5000 196   575 
10000 420   1215 
100000 3188   10497 
1000000 34489  114330 

私は疑問に思ってするのstd ::リストのパフォーマンスを来る方法ですがのstd ::ベクトル一貫して悪化している:Nのセットが、私は結果は下記の番号と同じオーダーで一貫している結果を得ます。 std :: vectorの場合、std :: vectorの基盤となる内部オブジェクトは時々サイズを変更する必要があるため、パフォーマンスは償却されることが予想されます(O)。私がやっていることは、リストの最後に要素を挿入することです。私はstd :: listがO(1)であると期待していました。だから、std :: listはstd :: vectorよりもうまくいくと示唆していますが、その反対は真実であるようです。

なぜこのようなことが起こっているのか、誰かが明らかにすることができれば幸いです。私は2015 MBPでg ++を使ってMacOS 10.12.6でコンパイルしています。

ありがとうございました。

編集:私は今std :: vector :: push_back()がO(1)を償却することを理解します。しかし、私には分かりませんが、なぜstd :: list :: push_back()はstd :: vector :: push_back()よりも一貫してパフォーマンスが悪いのですか?

+0

ありがとうございます。リンクは、std :: vector :: push_back()が償却されたO(1)を示唆しています。それでも私はstd :: list :: push_back()がstd :: list :: push_back()よりもずっと悪い理由を説明していません –

+7

リストに挿入するたびにメモリ割り当てが必要なので、ない。 – 1201ProgramAlarm

+0

@ 1201ProgramAlarmリストの明白な最適化は、メモリ割り当てのためのその要件を取り除くことです、私は推測しますが、リストでは毎回設定する必要がある次の要素への追加ポインタもあります。 'std :: vector/list cache(n)'であなたのプログラムを試して、比較のためのメモリ割り当てをなくしてください。 –

答えて

0

ベクトル挿入は、リストが常にO(n)である償却O(n)ではなく、償却定数(つまり償却O(1))であり、この状況ではベクトル容量は実際のサイズそれは余分なスペースを割り当てて、それが進むにつれていっぱいになるので、すべてのpush_backに対して割り当てが不要になります。

+2

cpprefより。com: "std :: listは、コンテナ内のどこからでも要素の一定時間の挿入と削除をサポートするコンテナです。"これはあなたの "リストは常にO(n)"のステートメントと矛盾しますか? –

関連する問題