[转]C++11中对容器的各种循环遍历的效率比较
今天做leetcode,拿C++,就一道简单题,被标答的时间完爆。看来刚学C++还是对底层理解太少了。主要是跟循环的速度有关,就上网搜了一波C++的遍历方法哪个快,搜到了一个博主的答案特别好,我总结一下搬运过来。C++11中对容器的各种循环遍历的效率比较测试方法是100 million个数字开平方,计算运行时间,根据这1亿个数字存储不同分为vecotr和list,根据运行版本的不同分为releas
·
今天做leetcode,拿C++,就一道简单题,被标答的时间完爆。看来刚学C++还是对底层理解太少了。
主要是跟循环的速度有关,就上网搜了一波C++的遍历方法哪个快,搜到了一个博主的答案特别好,我总结一下搬运过来。C++11中对容器的各种循环遍历的效率比较
测试方法是100 million个数字开平方,计算运行时间,根据这1亿个数字存储不同分为vecotr
和list
,根据运行版本的不同分为release
和debug
。这个代码我也没有运行过,我只是这篇答案的搬运工。
先把排序算法的代码搬运过来:
NormalForLoop
常规For循环:
void normalForLoop(const _Container& datas) {
TimeUsedGuard timeUsedGuard(__FUNCTION__);
size_t i = 0;
for (; i < datas.size(); ++i) {
useData(datas[i]);
}
}
NormalForLoopCallSizeOnce
调用一次size()
的常规For循环。
void normalForLoopCallSizeOnce(const _Container& datas)
{
TimeUsedGuard timeUsedGuard(__FUNCTION__);
size_t i = 0;
size_t size = datas.size();
for (; i < size; ++i)
{
useData(datas[i]);
}
}
Iterator
迭代器
void iterator(const _Container& datas)
{
TimeUsedGuard timeUsedGuard(__FUNCTION__);
auto pos = datas.cbegin();
for (; pos != datas.cend(); ++pos)
{
useData(*pos);
}
}
IteratorCallEndOnce
只调用一次cend()
的迭代器。
void iteratorCallCEndOnce(const _Container& datas)
{
TimeUsedGuard timeUsedGuard(__FUNCTION__);
auto pos = datas.cbegin();
auto end = datas.cend();
for (; pos != end; ++pos)
{
useData(*pos);
}
}
qtForEach
void qtForeach(const _Container& datas)
{
TimeUsedGuard timeUsedGuard(__FUNCTION__);
foreach (auto data, datas)
{
useData(data);
}
}
std::for_each
std::for_each
void stdForeach(const _Container& datas)
{
TimeUsedGuard timeUsedGuard(__FUNCTION__);
std::for_each(datas.cbegin(), datas.cend(), useData<typename _Container::value_type>);
}
rangeForLoop
范围For循环
void rangeForLoop(const _Container& datas)
{
TimeUsedGuard timeUsedGuard(__FUNCTION__);
for (auto data : datas)
{
useData(data);
}
}
rangeForLoopReference
对引用做范围For循环
void rangeForLoopReference(const _Container& datas)
{
TimeUsedGuard timeUsedGuard(__FUNCTION__);
for (auto& data : datas)
{
useData(data);
}
}
遍历速度
单位:毫秒ms.
每一列的最快者(及次快者)都用粗体标出。供大家参阅。
vector[debug] | vector[release] | list[debug] | list[release] | |
---|---|---|---|---|
NormalForLoopCallSizeOnce | 926 | 106 | - | - |
NormalForLoop | 1096 | 113 | - | - |
rangeForLoop | 1527 | 101 | 186 | 26 |
rangeForLoopReference | 1551 | 102 | 186 | 27 |
std::for_each | 1488 | 120 | 182 | 27 |
iteratorCallEndOnce | 1473 | 101 | 183 | 26 |
iterator | 1941 | 103 | 206 | 27 |
qtForEach | 1846 | 252 | 1493 | 743 |
写在最后
私以为,
vector
的遍历,用常规For循环,或者是把size()
调用提出的For循环,就很好。
list
的遍历,可以用范围(带引用)For循环,std::for_each
都行,如果要用迭代器,把end()
调用提出是一个加速手段。
更多推荐
已为社区贡献1条内容
所有评论(0)