今天做leetcode,拿C++,就一道简单题,被标答的时间完爆。看来刚学C++还是对底层理解太少了。
主要是跟循环的速度有关,就上网搜了一波C++的遍历方法哪个快,搜到了一个博主的答案特别好,我总结一下搬运过来。C++11中对容器的各种循环遍历的效率比较
测试方法是100 million个数字开平方,计算运行时间,根据这1亿个数字存储不同分为vecotr
和list
,根据运行版本的不同分为release
和debug
。这个代码我也没有运行过,我只是这篇答案的搬运工。
先把排序算法的代码搬运过来:
常规For循环:
void normalForLoop(const _Container& datas) { TimeUsedGuard timeUsedGuard(__FUNCTION__); size_t i = 0; for (; i < datas.size(); ++i) { useData(datas[i]); } }
调用一次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]); } }
迭代器
void iterator(const _Container& datas) { TimeUsedGuard timeUsedGuard(__FUNCTION__); auto pos = datas.cbegin(); for (; pos != datas.cend(); ++pos) { useData(*pos); } }
只调用一次cend()
的迭代器。
void iteratorCallCEndOnce(const _Container& datas) { TimeUsedGuard timeUsedGuard(__FUNCTION__); auto pos = datas.cbegin(); auto end = datas.cend(); for (; pos != end; ++pos) { useData(*pos); } }
void qtForeach(const _Container& datas) { TimeUsedGuard timeUsedGuard(__FUNCTION__); foreach (auto data, datas) { useData(data); } }
std::for_each
void stdForeach(const _Container& datas) { TimeUsedGuard timeUsedGuard(__FUNCTION__); std::for_each(datas.cbegin(), datas.cend(), useData<typename _Container::value_type>); }
范围For循环
void rangeForLoop(const _Container& datas) { TimeUsedGuard timeUsedGuard(__FUNCTION__); for (auto data : datas) { useData(data); } }
对引用做范围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()
调用提出是一个加速手段。