[转]C++11中对容器的各种循环遍历的效率比较

今天做leetcode,拿C++,就一道简单题,被标答的时间完爆。看来刚学C++还是对底层理解太少了。
主要是跟循环的速度有关,就上网搜了一波C++的遍历方法哪个快,搜到了一个博主的答案特别好,我总结一下搬运过来。C++11中对容器的各种循环遍历的效率比较

测试方法是100 million个数字开平方,计算运行时间,根据这1亿个数字存储不同分为vecotrlist,根据运行版本的不同分为releasedebug。这个代码我也没有运行过,我只是这篇答案的搬运工。

先把排序算法的代码搬运过来:

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()调用提出是一个加速手段。

上一篇:二叉树遍历


下一篇:Windows netstat 查看端口、进程占用