C++ for循环效率优化

C++ for循环效率优化

测试代码

main.cpp源代码

#include <iostream>
#include <vector>
#include "timer.h"
#include <algorithm>


struct QCJ
{
    int a;
    float b;
};

int main(int argc, char **argv)
{
    Timer timer;
    std::map<std::string, double> map_time;
    std::string log;

    const int size = 100000000;
    std::vector<QCJ> source(size);
    std::vector<QCJ> target(size);

    // method 1   for + push_back             531.456ms.
    timer.tic();
    for (size_t i = 0; i < source.size(); i++)
    {
      int a = source[i].a;
      float b = source[i].b;
      target.push_back(source[i]);
    }
    double time_m1 = timer.toc(true);
    log = "Method 1  for + push_back";
    std::cout <<  log << ": " << time_m1 << "ms." << std::endl;
    
    // method 1-1   for iterator + push_back   144.177ms.
    target.clear();
    timer.tic();
    for (auto itr = source.begin(); itr != source.end(); ++itr)
    {
      int a = itr->a;
      float b = itr->b;
      target.push_back(*itr);
    }
    double time_m1_1 = timer.toc(true);
    log = "method 1-1  for iterator + push_back";
    std::cout << log << ": " << time_m1_1 << "ms." << std::endl;
	
    // method 2   for + emplace    297.366ms.
    target.clear();
    timer.tic();
    for (size_t i = 0; i < source.size(); i++)
    {
      int a = source[i].a;
      float b = source[i].b;
      target.emplace_back(source[i]);
    }
    double time_m2 = timer.toc(true);
    std::cout << "method 2   for + emplace: " << time_m2 << "ms." << std::endl;

    // method 2-1   for iterator + emplace_back         296.168ms.
    target.clear();
    timer.tic();
    for (auto itr = source.begin(); itr != source.end(); ++itr)
    {
      int a = itr->a;
      float b = itr->b;
      target.emplace_back(*itr);
    }
    double time_m2_1 = timer.toc(true);
    std::cout << "method 2-1  for iterator + emplace_back: " << time_m2_1 << "ms." << std::endl;

    // method 3   for2 + push_back           148.236ms.
    target.clear();
    timer.tic();
    for (auto src : source)
    {
      int a = src.a;
      float b = src.b;
      target.push_back(src);
    }
    double time_m3 = timer.toc(true);
    std::cout << "method 3   for2 + push_back: " << time_m3 << "ms." << std::endl;

    // method 4   for2 + emplace_back     328.124ms.
    target.clear();
    timer.tic();
    for (auto src : source)
    {
      int a = src.a;
      float b = src.b;
      target.emplace_back(src);
    }
    double time_m4 = timer.toc(true);
    std::cout << "method 4   for2 + emplace_back: " << time_m4 << "ms." << std::endl;

    // method 5   for3 & + push_back     143.673ms.
    target.clear();
    timer.tic();
    for (auto &src : source)
    {
      int a = src.a;
      float b = src.b;
      target.push_back(src);
    }
    double time_m5 = timer.toc(true);
    std::cout << "method 5   for3 & + push_back: " << time_m5 << "ms." << std::endl;

    // method 6   for3 & + emplace_back      287.063ms.
    target.clear();
    timer.tic();
    for (auto &src : source)
    {
      int a = src.a;
      float b = src.b;
      target.emplace_back(src);
    }
    double time_m6 = timer.toc(true);
    log = "method 6   for3 & + emplace_back";
    std::cout <<  log << ": " << time_m6 << "ms." << std::endl;

    // method 7   for 临时引用 & + push_back    145.094ms.
    target.clear();
    timer.tic();
    for (size_t i = 0; i < source.size(); i++)
    {
      auto &QCJ = source[i];
      int a = QCJ.a;
      float b = QCJ.b;
      target.push_back(QCJ);
    }
    double time_m7 = timer.toc(true);
    log = "method 7   for 临时引用 & + push_back";
    std::cout <<  log << ": " << time_m7 << "ms." << std::endl;

    // method 8   for 临时引用 & + emplace_back    289.195ms.
    target.clear();
    timer.tic();
    for (size_t i = 0; i < source.size(); i++)
    {
      auto &QCJ = source[i];
      int a = QCJ.a;
      float b = QCJ.b;
      target.emplace_back(QCJ);
    }
    double time_m8 = timer.toc(true);
    log = "method 8   for 临时引用 & + emplace_back";
    std::cout <<  log << ": " << time_m8 << "ms." << std::endl;

    // method 9   for 临时引用  + std::copy   72.3075ms.
    target.clear();
    timer.tic();
    for (size_t i = 0; i < source.size(); i++)
    {
      auto &QCJ = source[i];
      int a = QCJ.a;
      float b = QCJ.b;
    }
    std::copy(source.begin(), source.end(), target.begin());
    double time_m9 = timer.toc(true);
    log = "method 9   for 临时引用  + std::copy";
    std::cout <<  log << ": " << time_m9 << "ms." << std::endl;

    // method 10   for3 & + std::copy   70.3496ms.
    target.clear();
    timer.tic();
    for (auto &src : source)
    {
      int a = src.a;
      float b = src.b;
    }
    std::copy(source.begin(), source.end(), target.begin());
    double time_m10 = timer.toc(true);
    log = "method 10   for3 & + std::copy";
    std::cout <<  log << ": " << time_m10 << "ms." << std::endl;

    // method 11   for_each + std::copy   71.0002ms.
    target.clear();
    int aa;
    float bb;
    timer.tic();
    auto Function = [&](QCJ &t){aa = t.a; bb = t.b;};
    std::for_each(source.begin(), source.end(), Function);
    std::copy(source.begin(), source.end(), target.begin());
    double time_m11 = timer.toc(true);
    log = "method 11   for_each + std::copy";
    std::cout <<  log << ": " << time_m11 << "ms." << std::endl;

结果:

Method 1  for + push_back: 531.456ms.
method 1-1  for iterator + push_back: 144.177ms.
method 2   for + emplace: 297.366ms.
method 2-1  for iterator + emplace_back: 296.168ms.
method 3   for2 + push_back: 148.236ms.
method 4   for2 + emplace_back: 328.124ms.
method 5   for3 & + push_back: 143.673ms.
method 6   for3 & + emplace_back: 287.063ms.
method 7   for 临时引用 & + push_back: 145.094ms.
method 8   for 临时引用 & + emplace_back: 289.195ms.
method 9   for 临时引用  + std::copy: 72.3075ms.
method 10   for3 & + std::copy: 70.3496ms.
method 11   for_each + std::copy: 71.0002ms.

结论

  1. 耗时: for(auto itr = items.begin(); itr != items.end(); itr++) 相当于 for(auto & item : items) < for(auto item : items) < for(size_t i = 0; i < items.size(); ++i)

  2. 耗时: 引用取值 < 拷贝取值

  3. 耗时: std::copy < 遍历赋值

  4. emplace_back效率不一定比push_back高;在 vector 这样的序列容器中,

    emplace_back比右值参数的push_back少做一次移动构造, 比左值参数的push_back少做一次拷贝构造;

for循环优先使用 for(auto itr = items.begin(); itr != items.end(); itr++)for(auto & item : items)for_each

拷贝vector数组时,优先使用std::copy

Reference

C++ for循环效率优化

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值