4

これは、ベクトルと配列を比較するための公正なテストですか?速度の差が大きすぎるようです。私のテストでは、アレイが10〜100倍高速であることが示されています。

#include "stdafx.h"
#include <iostream>
#include <vector>
#include <windows.h>
#include <stdint.h>

using namespace std;

double PCFreq = 0.0;
__int64 CounterStart = 0;

using namespace std;

void StartCounter()
{
    LARGE_INTEGER li;
    if(!QueryPerformanceFrequency(&li))
    std:cout << "QueryPerformanceFrequency failed!\n";

    PCFreq = double(li.QuadPart)/1000000000;

    QueryPerformanceCounter(&li);
    CounterStart = li.QuadPart;
}
double GetCounter()
{
    LARGE_INTEGER li;
    QueryPerformanceCounter(&li);
    return double(li.QuadPart-CounterStart)/PCFreq;
}

int _tmain(int argc, _TCHAR* argv[])
{
    //Can do 100,000 but not 1,000,000
    const int vectorsize = 100000;
    cout.precision(10);

    StartCounter();
    vector<int> test1(vectorsize);
    for(int i=0; i<vectorsize; i++){
        test1[i] = 5;
    }
    cout << GetCounter() << endl << endl;


    StartCounter();
    int test2[vectorsize];
    for(int i=0; i<vectorsize; i++){
        test2[i] = 5;
    }
    cout << GetCounter() << endl << endl;

    cout << test2[0];

    int t = 0;
    cin >> t;
    return 0;
}
4

1 に答える 1

12

それはあなたが比較しているものに依存します。

ベンチマークでは、セットアップ時間とアクセス時間の両方を一緒に測定します。std::vectorセットアップ時間が長くなることは間違いありません。これは、メモリを割り当ててから(標準の必要性により)すべての要素でデフォルトのコンストラクターを呼び出す必要があるためです。これはPODタイプの場合、ゼロ化を意味します。

したがって、アクセス時間を測定しようとしている場合、ベンチマークは正確ではありません。

ダイジェストするいくつかの数字は次のとおりです。

元のコード:

StartCounter();
vector<int> test1(vectorsize);

for(int i=0; i<vectorsize; i++){
    test1[i] = 5;
}
cout << GetCounter() << endl << endl;

時間:444353.5206


:を宣言して初期化した、タイミングを開始します。vector

vector<int> test1(vectorsize);

StartCounter();
for(int i=0; i<vectorsize; i++){
    test1[i] = 5;
}
cout << GetCounter() << endl << endl;

時間:15031.76101


そしてアレイの場合:

StartCounter();
int test2[vectorsize];
for(int i=0; i<vectorsize; i++){
    test2[i] = 5;
}
cout << GetCounter() << endl << endl;

時間:38129.345

宣言のタイミングに関係なく、時間はほぼ同じです。これは、関数へのエントリ時にスタック割り当てが一度に行われるためと考えられます。


基本的に、ベクトルメモリの割り当てと初期化には不釣り合いな時間がかかります。しかし、実際のループは高速です。

また、現在のベンチマークフレームワークにはまだ見た目の欠陥があることにも注意してください。各配列に対して1回だけパスします。したがって、キャッシュ効果と遅延割り当ては重要になります。

アレイの速度が低下した理由は、レイジーアロケーションが原因である可能性があります。アレイは割り当てられていますが、まだコミットされていません。レイジーアロケーションとは、最初のアクセス時にコミットされることを意味します。これには、ページフォールトとカーネルへのコンテキストスイッチが含まれます。


これは、ベンチマーク時間を増やすための外部ループを使用したより公平なテストです。

vector<int> test1(vectorsize);

StartCounter();
for (int c = 0; c < 10000; c++){
    for(int i=0; i<vectorsize; i++){
        test1[i] = 5;
    }
}
cout << GetCounter() << endl << endl;

時間:227330454.6

int test2[vectorsize];
memset(test2,0,sizeof(test2));

StartCounter();
for (int c = 0; c < 10000; c++){
    for(int i=0; i<vectorsize; i++){
        test2[i] = 5;
    }
}
cout << GetCounter() << endl << endl;
cout << test2[0];

時間:212286228.2

したがって、定常状態アクセスの場合、配列はベクトルよりも高速ではありません。適切にベンチマークを行うのは難しいことです。

于 2012-12-15T18:43:16.500 に答える