[英]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.