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