zoukankan      html  css  js  c++  java
  • C++11中对容器的各种循环遍历的效率比较

      1 #include "CycleTimeTst.h"
      2 #include <string>
      3 #include <vector>
      4 #include <list>
      5 #include <limits>
      6 #include <assert.h>
      7 #include <QTime>
      8 #include <QDebug>
      9 
     10 class TimeUsedGuard
     11 {
     12 public:
     13     TimeUsedGuard(const std::string& msg)
     14         : m_msg(msg)
     15         , m_time(QTime::currentTime())
     16     {
     17     }
     18     ~TimeUsedGuard()
     19     {
     20         qDebug() << m_msg.c_str() << "use time:" << m_time.elapsed() << "ms";
     21     }
     22 
     23 private:
     24     std::string     m_msg;
     25     QTime           m_time;
     26 };
     27 
     28 template <typename T>
     29 T useData(T val)
     30 {
     31     return std::sqrt(val);
     32 }
     33 
     34 template <typename _Container>
     35 void normalForLoop(const _Container& datas)
     36 {
     37     TimeUsedGuard timeUsedGuard(__FUNCTION__);
     38     size_t i = 0;
     39     for (; i < datas.size(); ++i)
     40     {
     41         useData(datas[i]);
     42     }
     43 }
     44 
     45 template <typename _Container>
     46 void normalForLoopCallSizeOnce(const _Container& datas)
     47 {
     48     TimeUsedGuard timeUsedGuard(__FUNCTION__);
     49     size_t i = 0;
     50     size_t size = datas.size();
     51     for (; i < size; ++i)
     52     {
     53         useData(datas[i]);
     54     }
     55 }
     56 
     57 template <typename _Container>
     58 void iterator(const _Container& datas)
     59 {
     60     TimeUsedGuard timeUsedGuard(__FUNCTION__);
     61     auto pos = datas.cbegin();
     62     for (; pos != datas.cend(); ++pos)
     63     {
     64         useData(*pos);
     65     }
     66 }
     67 
     68 template <typename _Container>
     69 void iteratorCallCEndOnce(const _Container& datas)
     70 {
     71     TimeUsedGuard timeUsedGuard(__FUNCTION__);
     72     auto pos = datas.cbegin();
     73     auto end = datas.cend();
     74     for (; pos != end; ++pos)
     75     {
     76         useData(*pos);
     77     }
     78 }
     79 
     80 template <typename _Container>
     81 void qtForeach(const _Container& datas)
     82 {
     83     TimeUsedGuard timeUsedGuard(__FUNCTION__);
     84     foreach (auto data, datas)
     85     {
     86         useData(data);
     87     }
     88 }
     89 
     90 template <typename _Container>
     91 void stdForeach(const _Container& datas)
     92 {
     93     TimeUsedGuard timeUsedGuard(__FUNCTION__);
     94     std::for_each(datas.cbegin(), datas.cend(), useData<typename _Container::value_type>);
     95 }
     96 
     97 template <typename _Container>
     98 void rangeForLoop(const _Container& datas)
     99 {
    100     TimeUsedGuard timeUsedGuard(__FUNCTION__);
    101     for (auto data : datas)
    102     {
    103         useData(data);
    104     }
    105 }
    106 
    107 template <typename _Container>
    108 void rangeForLoopReference(const _Container& datas)
    109 {
    110     TimeUsedGuard timeUsedGuard(__FUNCTION__);
    111     for (auto& data : datas)
    112     {
    113         useData(data);
    114     }
    115 }
    116 
    117 class CycleTimeTst
    118 {
    119 public:
    120     CycleTimeTst();
    121 };
    122 
    123 CycleTimeTst g_CycleTimeTst;
    124 CycleTimeTst::CycleTimeTst()
    125 {
    126     constexpr unsigned long MAX_AMOUNT = 100 * 1000 * 1000;
    127 
    128     // std::vector<int> datas;
    129     // for (unsigned long i = 1; i < MAX_AMOUNT; ++i)
    130     // {
    131     //     datas.push_back(i);
    132     // }
    133     std::list<double> datas;
    134     double d = 1.0;
    135     for (unsigned long i = 1; i < MAX_AMOUNT / 10; ++i)
    136     {
    137         datas.push_back(d);
    138     }
    139 
    140     // normalForLoop(datas);
    141     // normalForLoopCallSizeOnce(datas);
    142     iterator(datas);
    143     iteratorCallCEndOnce(datas);
    144     qtForeach(datas);
    145     stdForeach(datas);
    146     rangeForLoop(datas);
    147     rangeForLoopReference(datas);
    148     // vector<int> 100 * 1000 * 1000 times, debug & release:
    149     // normalForLoop use time: 1096 ms                   normalForLoop use time: 113 ms
    150     // normalForLoopCallSizeOnce use time: 926 ms        normalForLoopCallSizeOnce use time: 106 ms
    151     // iterator use time: 1941 ms                        iterator use time: 103 ms
    152     // iteratorCallCEndOnce use time: 1473 ms            iteratorCallCEndOnce use time: 101 ms
    153     // qtForeach use time: 1846 ms                       qtForeach use time: 262 ms
    154     // stdForeach use time: 1488 ms                      stdForeach use time: 120 ms
    155     // rangeForLoop use time: 1527 ms                    rangeForLoop use time: 101 ms
    156     // rangeForLoopReference use time: 1551 ms           rangeForLoopReference use time: 102 ms
    157 
    158     // list<double> 10 * 1000 * 1000 times, debug & release:
    159     // iterator use time: 206 ms                         iterator use time: 27 ms
    160     // iteratorCallCEndOnce use time: 183 ms             iteratorCallCEndOnce use time: 26 ms
    161     // qtForeach use time: 1493 ms                       qtForeach use time: 743 ms
    162     // stdForeach use time: 182 ms                       stdForeach use time: 27 ms
    163     // rangeForLoop use time: 186 ms                     rangeForLoop use time: 26 ms
    164     // rangeForLoopReference use time: 186 ms            rangeForLoopReference use time: 27 ms
    165 }

    个人总结:

    vector支持随机访问,但无通用性,当采用list后,就不能再使用了,不可取.

    迭代器与范围for循环所用时间无明显差异, qt提供的foreach显然是最差的方法, std算法for_each也还可以接受, 但范围for循环好看得多, 更好用啊!

    在循环中调用调用cend方法,会频繁创建一个新的迭代器(不停的构造与析构),另外还有函数调用开销,在debug版本结果来看似乎确实有一定的影响,但在realease版本下所花时间几乎相等,也许编译器有优化吧!

  • 相关阅读:
    Session的使用与Session的生命周期
    Long-Polling, Websockets, SSE(Server-Sent Event), WebRTC 之间的区别与使用
    十九、详述 IntelliJ IDEA 之 添加 jar 包
    十八、IntelliJ IDEA 常用快捷键 之 Windows 版
    十七、IntelliJ IDEA 中的 Maven 项目初体验及搭建 Spring MVC 框架
    十六、详述 IntelliJ IDEA 创建 Maven 项目及设置 java 源目录的方法
    十五、详述 IntelliJ IDEA 插件的安装及使用方法
    十四、详述 IntelliJ IDEA 提交代码前的 Code Analysis 机制
    十三、IntelliJ IDEA 中的版本控制介绍(下)
    十二、IntelliJ IDEA 中的版本控制介绍(中)
  • 原文地址:https://www.cnblogs.com/diysoul/p/7096795.html
Copyright © 2011-2022 走看看