使用std::vector时的细节

两个vector之间复制数据的效率比较试验_vector assign效率_半雨微凉丶的博客-CSDN博客前言在实际中经常遇到两个vector之间的赋值,实现很简单,方法也很多,但是你用的是不是最有效率的呢?所以就做了一个小实验,测试一下各种赋值方法之间的效率差异,仅供参考~示例代码:// vector_copy.cpp : Defines the entry point for the console application.//#include "stdafx.h"#incl...https://blog.csdn.net/myruo/article/details/90238655

6 个技巧,提升 C++11 的 vector 性能 - 技术翻译 - OSCHINA 社区https://www.oschina.net/translate/6-tips-supercharge-cpp-11-vector-performance?print

1.insert使用

1.1.以下代码会出core

std::vector<double> points;
std::vector<double> temp_points(10, 0.1);

points.insert(points.end(), temp_points.end(), temp_points.begin());

1.2尽量避免在头部insert

任何在 vetor 前部部做的插入操作其复杂度都是 O(n) 的。在前部插入数据十分低效,因为 vector 中的每个元素项都必须为新的项腾出空间而被复制。如果在 vector 前部连续插入多次,那可能需要重新评估你的总体架构。

做个有趣的尝试,下面是在 std::vector 前部做插入和在 std::list 前部部做插入的对比:

vector<BigTestStruct> sourceVector3, pushFrontTestVector;
FillVector(sourceVector3);
list<BigTestStruct> pushFrontTestList;
//Push 100k elements in front of the new vector -- this is horrible code !!! 
sw.Restart();
for (unsigned i = 1; i < sourceVector3.size(); ++i)
{
  pushFrontTestVector.insert(pushFrontTestVector.begin(), sourceVector3[i]);
}
cout << "Pushing in front of Vector :" << sw.ElapsedUs() << endl;
// push in front of a list
sw.Restart();
for (unsigned i = 0; i < sourceVector3.size(); ++i)
{
  pushFrontTestList.push_front(sourceVector3[i]);
}
cout << "Pushing in front of list :" << sw.ElapsedUs() << endl;

如果我运行这个测试10,其中使用一个包含100个元素的vector,那么输出结果如下:

Average of Pushing in front of Vector :11999.4
Average of Pushing in front of list :20.36

在 list 前部部插入操作比在 vector 前部部快大约58836%。不用感到奇怪,因为在 list 前部做元素插入的算法,其复杂度为 O(1)。显然,vector 包含元素越多,这个性能测试的结果会越差。

1.3在填充或者拷贝到 vector 的时候,应该使用赋值而不是 insert() 或push_back().

从一个 vector 取出元素来填充另一个 vector 的时候,常有三种方法 – 把旧的 vector 赋值给新的 vector,使用基于迭代器的 std::vector::insert() 或者使用基于循环的 std::vector::push_back()。这些方法都展示在下面:

vector<BigTestStruct> sourceVector, destinationVector;
FillVector(sourceVector);
// Assign sourceVector to destination vector
sw.Restart();
destinationVector = sourceVector;
cout << "Assigning Vector :" << sw.ElapsedUs() << endl;
//Using std::vector::insert()
vector<BigTestStruct> sourceVector1, destinationVector1;
FillVector(sourceVector1);
sw.Restart();
destinationVector1.insert(destinationVector1.end(),
  sourceVector1.begin(),
  sourceVector1.end());
cout << "Using insert() :" << sw.ElapsedUs() << endl;

这是它们的性能:

赋值: 589.54 us

insert(): 1321.27 us

push_back(): 5354.70 us

我们看到 vector 赋值比 insert() 快了 55.38%,比 push_back() 快了 89% 。

为什么会这样???

赋值非常有效率,因为它知道要拷贝的 vector 有多大,然后只需要通过内存管理一次性拷贝 vector 内部的缓存。

所以,想高效填充 vector,首先应尝试使用 assignment,然后再考虑基于迭代器的 insert(),最后考虑 push_back。当然,如果你需要从其它类型的容器拷贝元素到 vector 中,赋值的方式不可行。这种情况下,只好考虑基于迭代器的 insert()。

1.3 std::assign 与 赋值运算符 = 的区别

c++ - STL - assignment operator vs. `assign` member function - Stack Overflowhttps://stackoverflow.com/questions/19735395/stl-assignment-operator-vs-assign-member-function

2. std::vector::at() 

遍历 std::vector 元素的时候,避免使用.

遍历 vector 有如下三种方法:

  1. 使用迭代器

  2. 使用 std::vector::at() 成员函数

  3. 使用下标 – [ ] 运算符

下面展示了每种用法:

//Using an iterator
vector<BigTestStruct> testVectorSum;
FillVector(testVectorSum);
sw.Restart();
int sum = 0;
for (auto it = testVectorSum.begin(); it != testVectorSum.end(); ++it)
{
  sum = sum + it->iValue;
}
cout << "Using Iterator:" << sw.ElapsedUs() << endl;
  
//Using the at() member function
sw.Restart();
sum = 0;
for (unsigned i = 0; i < testVectorSum.size(); ++i)
{
  sum = sum + testVectorSum.at(i).iValue;
}
cout << "Using at() :" << sw.ElapsedUs() << endl;
  
// Using the subscript notation
sw.Restart();
sum = 0;
for (unsigned i = 0; i < testVectorSum.size(); ++i)
{
  sum = sum + testVectorSum[i].iValue;
}
cout << "Using subscripting:" << sw.ElapsedUs() << endl;

输出是:

Using Iterator:0
Using at() :3.73
Using subscripting:0

显而易见,用 std::vector::at() 函数访问 vector 元素是最慢的一个。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值