簡體   English   中英

使用標准的標准容器進行迭代

[英]iterating over std containers using standard for

從我學到的以std :: vector遍歷容器的方式是使用迭代器,如下所示:

for(vector<int>::iterator it = numbers.begin(); it != numbers.end(); it++)

我的問題是,為什么不使用standatd for而不是在容器上for迭代,它更快,因為不需要調用numbers.begin()numbers.end()函數。
從我的嘗試中,我發現使用for的速度比使用迭代器的速度快X 30。
我寫了這段代碼:

vector<int> numbers;
for (int i = 0; i < 5000000; i++)
{
    numbers.push_back(i);
}

time_t t = time(0);
struct tm * now = localtime(&t);
cout << now->tm_hour << ":" << now->tm_min << ":" <<  now->tm_sec << "\n";

for(vector<int>::iterator it = numbers.begin(); it != numbers.end(); it++)
{
    *it = 7;
}

t = time(0);
now = localtime(&t);
cout << now->tm_hour << ":" << now->tm_min << ":" <<  now->tm_sec << "\n";

int size = numbers.size();
for (int i = 0; i < size; i++)
{
    numbers[i] = i;
}

t = time(0);
now = localtime(&t);
cout << now->tm_hour << ":" << now->tm_min << ":" <<  now->tm_sec;

輸出為:

    19:28:25
    19:28:56
    19:28:57

看一下您的數字-30秒迭代一個簡單的向量? 那是CPU時間的永恆。 那里出問題了。

一些建議:

  • 該載體大約需要19MB。 數量不多,但是有可能導致堆碎片,或者如果計算機上加載了許多其他應用程序,則可能導致VM交換。 為了獲得可靠的數字,請關閉盡可能多的應用程序,並確保系統空閑。

  • 提示位於計時器內部,因此您正在測量iostream庫的各個部分的性能。 您停下時間之后計時部分之外進行偵察。

  • 一秒鍾的時鍾不夠精確,無法衡量性能指標。 使用timeval和gettimeofday()獲得微秒精度。

  • 僅對向量進行一次迭代,我就發現運行之間存在很大差異。 為了獲得更多可重復的結果,請多次迭代向量(例如500次)。 (這比使用較大的向量更好,后者可能會導致交換/碎片問題。)

  • 打開優化(例如g ++ -O3)。 循環運行得更快,時間差也要少得多。 內聯優化可能更有助於std :: vector <>代碼。

有了這些更改(如下),在我的計算機上,迭代器的速度比沒有優化的索引慢4倍,但使用-O1的迭代器要快一些 ,而使用-O3的迭代器則差不多。

#include <iostream>
#include <sys/time.h>
#include <vector>
using namespace std;

const unsigned N_REPS = 500;
const unsigned N_ITEMS = 5000000;

int print_elapsed(timeval start)
{
    timeval stop;
    gettimeofday(&stop, NULL);
    int elapsed = (stop.tv_sec * 1000000 + stop.tv_usec) - (start.tv_sec * 1000000 + start.tv_usec);
    cout << elapsed << "us" << endl;
    return elapsed;
}

int main()
{
    vector<int> numbers;
    numbers.reserve(N_ITEMS); // avoid heap fragmentation
    for (int i = 0; i < N_ITEMS; ++i)
        numbers.push_back(i);

    timeval start;
    gettimeofday(&start, NULL);

    for (unsigned r = 0; r < N_REPS; ++r)
        for (vector<int>::iterator it = numbers.begin(); it != numbers.end(); ++it)
            *it = r;

    int elapsed0 = print_elapsed(start);
    gettimeofday(&start, NULL);

    unsigned size = numbers.size();
    for (unsigned r = 0; r < N_REPS; ++r)
        for (unsigned i = 0; i < size; ++i)
            numbers[i] = r;

    int elapsed1 = print_elapsed(start);
    cout << 100 * float(elapsed1) / elapsed0 << '%' << endl;

    return 0;
}

使用迭代器可為您提供靈活性,即使您將容器類型更改為另一種,迭代代碼也將保持不變。 這是因為所有標准庫容器都提供了迭代器。 在某種程度上,它使您有機會編寫更多通用代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM