C++ STL vector遍历方式及其效率分析

C++ STL vector遍历方式及其效率分析

++i和i++区别

++i使用的是i执行完+1后的值可以直接使用,而i++是先使用i然后在对i进行+1这样就需要一个临时变量去进行转储,虽然只是一个简单的操作但是在循环中这一操作就会被循环次数而放大。如果i是一个简单的int型变量在很多编译器里面会优化这种写法,但是如果i是一个迭代器那么循环的性能就会收到影响,具体大小受到循环次数的约束。笔者亲测在QT中部分源码以及输出如下:

   std::vector<int> iv;
   int i;
    for(i=0;i<10000000;++i)
   {
        iv.push_back(i);
   }
   QDateTime dateTime = QDateTime::currentDateTime();
   qDebug()<<dateTime.toString("yyyy-MM-dd hh:mm:ss.zzz");
   auto iter=iv.begin();
   for(iter;iter!=iv.end();++iter)
   {
        int a = *iter;
   }
   dateTime = QDateTime::currentDateTime();
   qDebug()<<dateTime.toString("yyyy-MM-dd hh:mm:ss.zzz");
   iter=iv.begin();
   for(iter;iter!=iv.end();iter++)
   {
        int a = *iter;
   }
   dateTime = QDateTime::currentDateTime();
   qDebug()<<dateTime.toString("yyyy-MM-dd hh:mm:ss.zzz");


输出:
"2021-10-19 11:29:11.488"
"2021-10-19 11:29:11.593"
"2021-10-19 11:29:11.738"
++iter循环1000万次耗时105毫秒
iter++循环1000万次耗时145毫秒

由上例可以看出++iter和iter++的区别

下标遍历

直接上代码:

   std::vector<int> iv;
   int i;
   for(i=0;i<10000000;++i)
   {
        iv.push_back(i);
   }
   int size = iv.size();
   QDateTime dateTime = QDateTime::currentDateTime();
   qDebug()<<dateTime.toString("yyyy-MM-dd hh:mm:ss.zzz");
   for(i=0;i<size;++i)
   {
        int a = iv[i];
   }
   dateTime = QDateTime::currentDateTime();
   qDebug()<<dateTime.toString("yyyy-MM-dd hh:mm:ss.zzz");
   输出为:
   "2021-10-19 11:56:25.258"
   "2021-10-19 11:56:25.280"
   循环1000万次耗时22毫秒
 

使用at方法取值:

   std::vector<int> iv;
   int i;
   for(i=0;i<10000000;++i)
   {
        iv.push_back(i);
   }
   int size = iv.size();
   QDateTime dateTime = QDateTime::currentDateTime();
   qDebug()<<dateTime.toString("yyyy-MM-dd hh:mm:ss.zzz");
   for(i=0;i<size;++i)
   {
        int a = iv.at(i);
   }
   dateTime = QDateTime::currentDateTime();
   qDebug()<<dateTime.toString("yyyy-MM-dd hh:mm:ss.zzz");
   输出为:
  "2021-10-19 13:28:21.609"
  "2021-10-19 13:28:21.699"
   循环1000万次耗时90毫秒

迭代器遍历

直接上代码:

  std::vector<int> iv;
  for(i=0;i<10000000;++i)
   {
        iv.push_back(i);
   }
   QDateTime dateTime = QDateTime::currentDateTime();
   qDebug()<<dateTime.toString("yyyy-MM-dd hh:mm:ss.zzz");
   auto iter=iv.begin();
   for(iter;iter!=iv.end();++iter)
   {
        int a = *iter;
   }
   dateTime = QDateTime::currentDateTime();
   qDebug()<<dateTime.toString("yyyy-MM-dd hh:mm:ss.zzz");
   输出:
   "2021-10-19 11:56:25.280"
   "2021-10-19 11:56:25.382"
   耗时102毫秒

for_each遍历

直接上代码:

template<typename T>
void fun(const T a)
{
    int b=a;
}
int main(int argc, char *argv[])
{
   std::vector<int> iv;
   int i;
   for(i=0;i<10000000;++i)
   {
        iv.push_back(i);
   }
   QDateTime dateTime = QDateTime::currentDateTime();
   qDebug()<<dateTime.toString("yyyy-MM-dd hh:mm:ss.zzz");
   std::for_each(iv.begin(),iv.end(),fun<int>);
   dateTime = QDateTime::currentDateTime();
   qDebug()<<dateTime.toString("yyyy-MM-dd hh:mm:ss.zzz");
}
输出为:
"2021-10-19 13:25:01.119"
"2021-10-19 13:25:01.199"
耗时90毫秒

总结

由上面例子可以看出,vector遍历最快的是下标遍历,但是下表遍历可能会出现超出范围的风险现,但是如果使用at方法获取vector中的值会导致效率降低。
下面科普下计算时间和电脑CPU之间的关系。现在普遍CPU的主频是1GHz到4GHz,意思是CPU一秒处理基础运算的次数,由此可以换算出一毫秒CPU处理基础运算的次数这里为了直观的数据体验使用1000为进制单位代替1024,一毫秒CPU可以运算100万到400万次 ,1000万次循环下标遍历和迭代器遍历可以差80毫秒也就是可以减少CPU基础运算800万到3200万次(假设CPU满负荷运算节省的80毫秒可以用来运算其他功能),可以推算出大约每10次循环可以节省8到32次基础运算。当然以上推论都是估算如有问题望指正。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值